⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biginteger.java

📁 J2ME加密算法的代码!里面包括常用的算法
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        return nBitLength;    }    //    // bitLen(val) is the number of bits in val.    //    static int bitLen(int w)    {        // Binary search - decision tree (5 tests, rarely 6)        return (w < 1 << 15 ? (w < 1 << 7                ? (w < 1 << 3 ? (w < 1 << 1                        ? (w < 1 << 0 ? (w < 0 ? 32 : 0) : 1)                        : (w < 1 << 2 ? 2 : 3)) : (w < 1 << 5                        ? (w < 1 << 4 ? 4 : 5)                        : (w < 1 << 6 ? 6 : 7)))                : (w < 1 << 11                        ? (w < 1 << 9 ? (w < 1 << 8 ? 8 : 9) : (w < 1 << 10 ? 10 : 11))                        : (w < 1 << 13 ? (w < 1 << 12 ? 12 : 13) : (w < 1 << 14 ? 14 : 15)))) : (w < 1 << 23 ? (w < 1 << 19                ? (w < 1 << 17 ? (w < 1 << 16 ? 16 : 17) : (w < 1 << 18 ? 18 : 19))                : (w < 1 << 21 ? (w < 1 << 20 ? 20 : 21) : (w < 1 << 22 ? 22 : 23))) : (w < 1 << 27                ? (w < 1 << 25 ? (w < 1 << 24 ? 24 : 25) : (w < 1 << 26 ? 26 : 27))                : (w < 1 << 29 ? (w < 1 << 28 ? 28 : 29) : (w < 1 << 30 ? 30 : 31)))));    }    public int compareTo(Object o)    {        return compareTo((BigInteger)o);    }    /**     * unsigned comparison on two arrays - note the arrays may     * start with leading zeros.     */    private int compareTo(int xIndx, int[] x, int yIndx, int[] y)    {        while (xIndx != x.length && x[xIndx] == 0)        {            xIndx++;        }        while (yIndx != y.length && y[yIndx] == 0)        {            yIndx++;        }        if ((x.length - xIndx) < (y.length - yIndx))        {            return -1;        }        if ((x.length - xIndx) > (y.length - yIndx))        {            return 1;        }        // lengths of magnitudes the same, test the magnitude values        while (xIndx < x.length)        {            long v1 = (long)(x[xIndx++]) & IMASK;            long v2 = (long)(y[yIndx++]) & IMASK;            if (v1 < v2)            {                return -1;            }            if (v1 > v2)            {                return 1;            }        }        return 0;    }    public int compareTo(BigInteger val)    {        if (sign < val.sign)            return -1;        if (sign > val.sign)            return 1;        if (sign == 0)            return 0;        return sign * compareTo(0, magnitude, 0, val.magnitude);    }    /**     * return z = x / y - done in place (z value preserved, x contains the     * remainder)     */    private int[] divide(int[] x, int[] y)    {        int xyCmp = compareTo(0, x, 0, y);        int[] count;        if (xyCmp > 0)        {            int[] c;            int shift = bitLength(0, x) - bitLength(0, y);            if (shift > 1)            {                c = shiftLeft(y, shift - 1);                count = shiftLeft(ONE.magnitude, shift - 1);                if (shift % 32 == 0)                {                    // Special case where the shift is the size of an int.                    int countSpecial[] = new int[shift / 32 + 1];                    System.arraycopy(count, 0, countSpecial, 1, countSpecial.length - 1);                    countSpecial[0] = 0;                    count = countSpecial;                }            }            else            {                c = new int[x.length];                count = new int[1];                System.arraycopy(y, 0, c, c.length - y.length, y.length);                count[0] = 1;            }            int[] iCount = new int[count.length];            subtract(0, x, 0, c);            System.arraycopy(count, 0, iCount, 0, count.length);            int xStart = 0;            int cStart = 0;            int iCountStart = 0;            for (; ; )            {                int cmp = compareTo(xStart, x, cStart, c);                while (cmp >= 0)                {                    subtract(xStart, x, cStart, c);                    add(count, iCount);                    cmp = compareTo(xStart, x, cStart, c);                }                xyCmp = compareTo(xStart, x, 0, y);                if (xyCmp > 0)                {                    if (x[xStart] == 0)                    {                        xStart++;                    }                    shift = bitLength(cStart, c) - bitLength(xStart, x);                    if (shift == 0)                    {                        c = shiftRightOne(cStart, c);                        iCount = shiftRightOne(iCountStart, iCount);                    }                    else                    {                        c = shiftRight(cStart, c, shift);                        iCount = shiftRight(iCountStart, iCount, shift);                    }                    if (c[cStart] == 0)                    {                        cStart++;                    }                    if (iCount[iCountStart] == 0)                    {                        iCountStart++;                    }                }                else if (xyCmp == 0)                {                    add(count, ONE.magnitude);                    for (int i = xStart; i != x.length; i++)                    {                        x[i] = 0;                    }                    break;                }                else                {                    break;                }            }        }        else if (xyCmp == 0)        {            count = new int[1];            count[0] = 1;        }        else        {            count = new int[1];            count[0] = 0;        }        return count;    }    public BigInteger divide(BigInteger val) throws ArithmeticException    {        if (val.sign == 0)        {            throw new ArithmeticException("Divide by zero");        }        if (sign == 0)        {            return BigInteger.ZERO;        }        if (val.compareTo(BigInteger.ONE) == 0)        {            return this;        }        int[] mag = new int[this.magnitude.length];        System.arraycopy(this.magnitude, 0, mag, 0, mag.length);        return new BigInteger(this.sign * val.sign, divide(mag, val.magnitude));    }    public BigInteger[] divideAndRemainder(BigInteger val) throws ArithmeticException    {        if (val.sign == 0)        {            throw new ArithmeticException("Divide by zero");        }        BigInteger biggies[] = new BigInteger[2];        if (sign == 0)        {            biggies[0] = biggies[1] = BigInteger.ZERO;            return biggies;        }        if (val.compareTo(BigInteger.ONE) == 0)        {            biggies[0] = this;            biggies[1] = BigInteger.ZERO;            return biggies;        }        int[] remainder = new int[this.magnitude.length];        System.arraycopy(this.magnitude, 0, remainder, 0, remainder.length);        int[] quotient = divide(remainder, val.magnitude);        biggies[0] = new BigInteger(this.sign * val.sign, quotient);        biggies[1] = new BigInteger(this.sign, remainder);        return biggies;    }    public boolean equals(Object val)    {        if (val == this)            return true;        if (!(val instanceof BigInteger))            return false;        BigInteger biggie = (BigInteger)val;        if (biggie.sign != sign || biggie.magnitude.length != magnitude.length)            return false;        for (int i = 0; i < magnitude.length; i++)        {            if (biggie.magnitude[i] != magnitude[i])                return false;        }        return true;    }    public BigInteger gcd(BigInteger val)    {        if (val.sign == 0)            return this.abs();        else if (sign == 0)            return val.abs();        BigInteger r;        BigInteger u = this;        BigInteger v = val;        while (v.sign != 0)        {            r = u.mod(v);            u = v;            v = r;        }        return u;    }    public int hashCode()    {        int hc = magnitude.length;        if (magnitude.length > 0)        {            hc ^= magnitude[0];            if (magnitude.length > 1)            {                hc ^= magnitude[magnitude.length - 1];            }        }        return sign < 0 ? ~hc : hc;    }    public int intValue()    {        if (magnitude.length == 0)        {            return 0;        }        if (sign < 0)        {            return -magnitude[magnitude.length - 1];        }        else        {            return magnitude[magnitude.length - 1];        }    }    /**     * return whether or not a BigInteger is probably prime with a     * probability of 1 - (1/2)**certainty.     * <p>     * From Knuth Vol 2, pg 395.     */    public boolean isProbablePrime(int certainty)    {        if (certainty <= 0)            return true;        if (sign == 0)            return false;        BigInteger n = this.abs();        if (!n.testBit(0))            return n.equals(TWO);        if (n.equals(ONE))            return false;        int test = n.remainder(smallPrimesProduct);        for (int index = 0; index < smallPrimes.length; ++index)        {            int smallPrime = smallPrimes[index];            if (test % smallPrime == 0)                return n.bitLength() <= 5 && n.intValue() == smallPrime;        }        //        // let n = 1 + 2^kq        //        BigInteger nMinusOne = n.subtract(ONE);        BigInteger q = nMinusOne;        int k = q.getLowestSetBit();        q = q.shiftRight(k);        Random rnd = new Random();        do        {            BigInteger x;            do            {                x = new BigInteger(n.bitLength(), rnd);            }            // NB: Spec says 0 < x < n, but 1 is trivial            while (x.compareTo(ONE) <= 0 || x.compareTo(n) >= 0);            BigInteger y = x.modPow(q, n);            if (!y.equals(ONE))            {                // check already = x.ModPow(q << 0, n)                int r = 0;                while (!y.equals(nMinusOne))                {                    if (++r == k)                        return false;                    // check becomes a.ModPow(q << r, n)                    y = y.modPow(TWO, n);                }            }            certainty -= 2; // composites pass for only 1/4 possible 'x'        }        while (certainty > 0);        return true;    }    public long longValue()    {        long val = 0;        if (magnitude.length == 0)        {            return 0;        }        if (magnitude.length > 1)        {            val = ((long)magnitude[magnitude.length - 2] << 32)                    | (magnitude[magnitude.length - 1] & IMASK);        }        else        {            val = (magnitude[magnitude.length - 1] & IMASK);        }        if (sign < 0)        {            return -val;        }        else        {            return val;        }    }    public BigInteger max(BigInteger val)    {        return (compareTo(val) > 0) ? this : val;    }    public BigInteger min(BigInteger val)    {        return (compareTo(val) < 0) ? this : val;    }    public BigInteger mod(BigInteger m) throws ArithmeticException    {        if (m.sign <= 0)        {            throw new ArithmeticException("BigInteger: modulus is not positive");        }        BigInteger biggie = this.remainder(m);        return (biggie.sign >= 0 ? biggie : biggie.add(m));    }    public BigInteger modInverse(BigInteger m) throws ArithmeticException    {        if (m.sign != 1)        {            throw new ArithmeticException("Modulus must be positive");        }        BigInteger x = new BigInteger();        BigInteger y = new BigInteger();        BigInteger gcd = BigInteger.extEuclid(this, m, x, y);        if (!gcd.equals(BigInteger.ONE))        {            throw new ArithmeticException("Numbers not relatively prime.");        }        if (x.compareTo(BigInteger.ZERO) < 0)        {            x = x.add(m);        }        return x;    }    /**     * Calculate the numbers u1, u2, and u3 such that:     *     * u1 * a + u2 * b = u3     *     * where u3 is the greatest common divider of a and b.     * a and b using the extended Euclid algorithm (refer p. 323     * of The Art of Computer Programming vol 2, 2nd ed).     * This also seems to have the side effect of calculating     * some form of multiplicative inverse.     *     * @param a    First number to calculate gcd for     * @param b    Second number to calculate gcd for     * @param u1Out      the return object for the u1 value     * @param u2Out      the return object for the u2 value     * @return     The greatest common divisor of a and b     */    private static BigInteger extEuclid(BigInteger a, BigInteger b, BigInteger u1Out,            BigInteger u2Out)    {        BigInteger res;        BigInteger u1 = BigInteger.ONE;        BigInteger u3 = a;        BigInteger v1 = BigInteger.ZERO;        BigInteger v3 = b;        while (v3.compareTo(BigInteger.ZERO) > 0)        {            BigInteger q, tn;            q = u3.divide(v3);            tn = u1.subtract(v1.multiply(q));            u1 = v1;            v1 = tn;            tn = u3.subtract(v3.multiply(q));            u3 = v3;            v3 = tn;        }        u1Out.sign = u1.sign;        u1Out.magnitude = u1.magnitude;        res = u3.subtract(u1.multiply(a)).divide(b);        u2Out.sign = res.sign;        u2Out.magnitude = res.magnitude;        return u3;    }    /**     * zero out the array x     */    private void zero(int[] x)    {        for (int i = 0; i != x.length; i++)        {            x[i] = 0;        }    }    public BigInteger modPow(BigInteger exponent, BigInteger m) throws ArithmeticException    {        if (m.sign < 1)        {            throw new ArithmeticException("Modulus must be positive");        }        if (m.equals(ONE))        {            return ZERO;        }        // Zero exponent check        if (exponent.sign == 0)        {            return ONE;        }        if (sign == 0)            return ZERO;        int[] zVal = null;        int[] yAccum = null;        int[] yVal;        // Montgomery exponentiation is only possible if the modulus is odd,        // but AFAIK, this is always the case for crypto algo's        boolean useMonty = ((m.magnitude[m.magnitude.length - 1] & 1) == 1);        long mQ = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -