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

📄 biginteger.java

📁 J2ME加密算法的代码!里面包括常用的算法
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package java.math;import java.util.Random;import java.util.Stack;public class BigInteger{    private int sign; // -1 means -ve; +1 means +ve; 0 means 0;    private int[] magnitude; // array of ints with [0] being the most significant    private int nBits = -1; // cache bitCount() value    private int nBitLength = -1; // cache bitLength() value    private static final long IMASK = 0xffffffffL;    private long mQuote = -1L; // -m^(-1) mod b, b = 2^32 (see Montgomery mult.)        private BigInteger()    {    }    private BigInteger(int signum, int[] mag)    {        sign = signum;        if (mag.length > 0)        {            int i = 0;            while (i < mag.length && mag[i] == 0)            {                i++;            }            if (i == 0)            {                magnitude = mag;            }            else            {                // strip leading 0 bytes                int[] newMag = new int[mag.length - i];                System.arraycopy(mag, i, newMag, 0, newMag.length);                magnitude = newMag;                if (newMag.length == 0)                    sign = 0;            }        }        else        {            magnitude = mag;            sign = 0;        }    }    public BigInteger(String sval) throws NumberFormatException    {        this(sval, 10);    }    public BigInteger(String sval, int rdx) throws NumberFormatException    {        if (sval.length() == 0)        {            throw new NumberFormatException("Zero length BigInteger");        }        if (rdx < Character.MIN_RADIX || rdx > Character.MAX_RADIX)        {            throw new NumberFormatException("Radix out of range");        }        int index = 0;        sign = 1;        if (sval.charAt(0) == '-')        {            if (sval.length() == 1)            {                throw new NumberFormatException("Zero length BigInteger");            }            sign = -1;            index = 1;        }        // strip leading zeros from the string value        while (index < sval.length() && Character.digit(sval.charAt(index), rdx) == 0)        {            index++;        }        if (index >= sval.length())        {            // zero value - we're done            sign = 0;            magnitude = new int[0];            return;        }        //////        // could we work out the max number of ints required to store        // sval.length digits in the given base, then allocate that        // storage in one hit?, then generate the magnitude in one hit too?        //////        BigInteger b = BigInteger.ZERO;        BigInteger r = valueOf(rdx);        while (index < sval.length())        {            // (optimise this by taking chunks of digits instead?)            b = b.multiply(r).add(valueOf(Character.digit(sval.charAt(index), rdx)));            index++;        }        magnitude = b.magnitude;        return;    }    public BigInteger(byte[] bval) throws NumberFormatException    {        if (bval.length == 0)        {            throw new NumberFormatException("Zero length BigInteger");        }        sign = 1;        if (bval[0] < 0)        {            sign = -1;        }        magnitude = makeMagnitude(bval, sign);        if (magnitude.length == 0) {            sign = 0;        }    }    /**     * If sign >= 0, packs bytes into an array of ints, most significant first     * If sign <  0, packs 2's complement of bytes into      * an array of ints, most significant first,     * adding an extra most significant byte in case bval = {0x80, 0x00, ..., 0x00}     *     * @param bval     * @param sign     * @return     */    private int[] makeMagnitude(byte[] bval, int sign)    {        if (sign >= 0) {            int i;            int[] mag;            int firstSignificant;            // strip leading zeros            for (firstSignificant = 0; firstSignificant < bval.length                    && bval[firstSignificant] == 0; firstSignificant++);            if (firstSignificant >= bval.length)            {                return new int[0];            }            int nInts = (bval.length - firstSignificant + 3) / 4;            int bCount = (bval.length - firstSignificant) % 4;                        if (bCount == 0)                bCount = 4;            // n = k * (n / k) + n % k            // bval.length - firstSignificant + 3 = 4 * nInts + bCount - 1            // bval.length - firstSignificant + 4 - bCount = 4 * nInts            mag = new int[nInts];            int v = 0;            int magnitudeIndex = 0;            for (i = firstSignificant; i < bval.length; i++)            {                // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts                // 1 <= bCount <= 4                v <<= 8;                v |= bval[i] & 0xff;                bCount--;                if (bCount <= 0)                {                    mag[magnitudeIndex] = v;                    magnitudeIndex++;                    bCount = 4;                    v = 0;                }            }            // 4 - bCount + 4 * magnitudeIndex = 4 * nInts            // bCount = 4 * (1 + magnitudeIndex - nInts)            // 1 <= bCount <= 4            // So bCount = 4 and magnitudeIndex = nInts = mag.length//            if (magnitudeIndex < mag.length)//            {//                mag[magnitudeIndex] = v;//            }            return mag;        }        else {            int i;            int[] mag;            int firstSignificant;                        // strip leading -1's            for (firstSignificant = 0; firstSignificant < bval.length - 1                    && bval[firstSignificant] == 0xff; firstSignificant++);            int nBytes = bval.length;            boolean leadingByte = false;            // check for -2^(n-1)            if (bval[firstSignificant] == 0x80) {                for (i = firstSignificant + 1; i < bval.length; i++) {                    if (bval[i] != 0) {                        break;                    }                }                if (i == bval.length) {                    nBytes++;                    leadingByte = true;                }            }            int nInts = (nBytes - firstSignificant + 3) / 4;            int bCount = (nBytes - firstSignificant) % 4;            if (bCount == 0)                bCount = 4;            // n = k * (n / k) + n % k            // nBytes - firstSignificant + 3 = 4 * nInts + bCount - 1            // nBytes - firstSignificant + 4 - bCount = 4 * nInts            // 1 <= bCount <= 4            mag = new int[nInts];            int v = 0;            int magnitudeIndex = 0;            // nBytes + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts            // 1 <= bCount <= 4            if (leadingByte) {                // bval.length + 1 + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts                bCount--;                // bval.length + 1 + 4 - (bCount + 1) - i + 4 * magnitudeIndex = 4 * nInts                // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts                if (bCount <= 0)                {                    magnitudeIndex++;                    bCount = 4;                }                // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts                // 1 <= bCount <= 4            }            for (i = firstSignificant; i < bval.length; i++)            {                // bval.length + 4 - bCount - i + 4 * magnitudeIndex = 4 * nInts                // 1 <= bCount <= 4                v <<= 8;                v |= ~bval[i] & 0xff;                bCount--;                if (bCount <= 0)                {                    mag[magnitudeIndex] = v;                    magnitudeIndex++;                    bCount = 4;                    v = 0;                }            }            // 4 - bCount + 4 * magnitudeIndex = 4 * nInts            // 1 <= bCount <= 4            // bCount = 4 * (1 + magnitudeIndex - nInts)            // 1 <= bCount <= 4            // So bCount = 4 and magnitudeIndex = nInts = mag.length//            if (magnitudeIndex < mag.length)//            {//                mag[magnitudeIndex] = v;//            }            return inc(mag);        }    }    public BigInteger(int sign, byte[] mag) throws NumberFormatException    {        if (sign < -1 || sign > 1)        {            throw new NumberFormatException("Invalid sign value");        }        if (sign == 0)        {            this.sign = 0;            this.magnitude = new int[0];            return;        }        // copy bytes        this.magnitude = makeMagnitude(mag, 1);        this.sign = sign;    }    public BigInteger(int numBits, Random rnd) throws IllegalArgumentException    {        if (numBits < 0)        {            throw new IllegalArgumentException("numBits must be non-negative");        }        int nBytes = (numBits + 7) / 8;        byte[] b = new byte[nBytes];        if (nBytes > 0)        {            nextRndBytes(rnd, b);            // strip off any excess bits in the MSB            b[0] &= rndMask[8 * nBytes - numBits];        }        this.magnitude = makeMagnitude(b, 1);        this.sign = 1;        this.nBits = -1;        this.nBitLength = -1;    }    private static final int BITS_PER_BYTE = 8;    private static final int BYTES_PER_INT = 4;    /**     * strictly speaking this is a little dodgey from a compliance     * point of view as it forces people to be using SecureRandom as     * well, that being said - this implementation is for a crypto     * library and you do have the source!     */    private void nextRndBytes(Random rnd, byte[] bytes)    {        int numRequested = bytes.length;        int numGot = 0,         r = 0;        if (rnd instanceof java.security.SecureRandom)        {            ((java.security.SecureRandom)rnd).nextBytes(bytes);        }        else        {            for (; ; )            {                for (int i = 0; i < BYTES_PER_INT; i++)                {                    if (numGot == numRequested)                    {                        return;                    }                    r = (i == 0 ? rnd.nextInt() : r >> BITS_PER_BYTE);                    bytes[numGot++] = (byte)r;                }            }        }    }    private static final byte[] rndMask = {(byte)255, 127, 63, 31, 15, 7, 3, 1};    public BigInteger(int bitLength, int certainty, Random rnd) throws ArithmeticException    {        int nBytes = (bitLength + 7) / 8;        byte[] b = new byte[nBytes];        do        {            if (nBytes > 0)            {                nextRndBytes(rnd, b);                // strip off any excess bits in the MSB                int xBits = 8 * nBytes - bitLength;                b[0] &= rndMask[xBits];                b[0] |= (byte)(1 << (7 - xBits));            }            this.magnitude = makeMagnitude(b, 1);            this.sign = 1;            this.nBits = -1;            this.nBitLength = -1;            this.mQuote = -1L;                        if (certainty > 0 && bitLength > 2)            {                this.magnitude[this.magnitude.length - 1] |= 1;            }        } while (this.bitLength() != bitLength || !this.isProbablePrime(certainty));    }    public BigInteger abs()    {        return (sign >= 0) ? this : this.negate();    }    /**     * return a = a + b - b preserved.     */    private int[] add(int[] a, int[] b)    {        int tI = a.length - 1;        int vI = b.length - 1;        long m = 0;        while (vI >= 0)        {            m += (((long)a[tI]) & IMASK) + (((long)b[vI--]) & IMASK);            a[tI--] = (int)m;            m >>>= 32;        }        while (tI >= 0 && m != 0)        {            m += (((long)a[tI]) & IMASK);            a[tI--] = (int)m;            m >>>= 32;        }        return a;    }    /**     * return a = a + 1.     */    private int[] inc(int[] a)    {        int tI = a.length - 1;        long m = 0;        m = (((long)a[tI]) & IMASK) + 1L;        a[tI--] = (int)m;        m >>>= 32;        while (tI >= 0 && m != 0)        {            m += (((long)a[tI]) & IMASK);            a[tI--] = (int)m;            m >>>= 32;        }        return a;    }    public BigInteger add(BigInteger val) throws ArithmeticException    {        if (val.sign == 0 || val.magnitude.length == 0)            return this;        if (this.sign == 0 || this.magnitude.length == 0)            return val;        if (val.sign < 0)        {            if (this.sign > 0)                return this.subtract(val.negate());        }        else        {            if (this.sign < 0)                return val.subtract(this.negate());        }        return addToMagnitude(val.magnitude);    }    private BigInteger addToMagnitude(        int[] magToAdd)    {        int[] big, small;        if (this.magnitude.length < magToAdd.length)        {            big = magToAdd;            small = this.magnitude;        }        else        {            big = this.magnitude;            small = magToAdd;        }        // Conservatively avoid over-allocation when no overflow possible        int limit = Integer.MAX_VALUE;        if (big.length == small.length)            limit -= small[0];        boolean possibleOverflow = (big[0] ^ (1 << 31)) >= limit;        int extra = possibleOverflow ? 1 : 0;        int[] bigCopy = new int[big.length + extra];        System.arraycopy(big, 0, bigCopy, extra, big.length);        bigCopy = add(bigCopy, small);        return new BigInteger(this.sign, bigCopy);    }    public int bitCount()    {        if (nBits == -1)        {            nBits = 0;            for (int i = 0; i < magnitude.length; i++)            {                nBits += bitCounts[magnitude[i] & 0xff];                nBits += bitCounts[(magnitude[i] >> 8) & 0xff];                nBits += bitCounts[(magnitude[i] >> 16) & 0xff];                nBits += bitCounts[(magnitude[i] >> 24) & 0xff];            }        }        return nBits;    }    private final static byte[] bitCounts = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1,        2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,        4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,        4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,        3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2,        3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3,        3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6,        7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,        5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5,        6, 6, 7, 6, 7, 7, 8};    private int bitLength(int indx, int[] mag)    {        int bitLength;        if (mag.length == 0)        {            return 0;        }        else        {            while (indx != mag.length && mag[indx] == 0)            {                indx++;            }            if (indx == mag.length)            {                return 0;            }            // bit length for everything after the first int            bitLength = 32 * ((mag.length - indx) - 1);            // and determine bitlength of first int            bitLength += bitLen(mag[indx]);            if (sign < 0)            {                // Check if magnitude is a power of two                boolean pow2 = ((bitCounts[mag[indx] & 0xff])                        + (bitCounts[(mag[indx] >> 8) & 0xff])                        + (bitCounts[(mag[indx] >> 16) & 0xff]) + (bitCounts[(mag[indx] >> 24) & 0xff])) == 1;                for (int i = indx + 1; i < mag.length && pow2; i++)                {                    pow2 = (mag[i] == 0);                }                bitLength -= (pow2 ? 1 : 0);            }        }        return bitLength;    }    public int bitLength()    {        if (nBitLength == -1)        {            if (sign == 0)            {                nBitLength = 0;            }            else            {                nBitLength = bitLength(0, magnitude);            }        }

⌨️ 快捷键说明

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