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

📄 biginteger.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
  private static int[] trustedStripLeadingZeroInts(int val[]) {
    int byteLength = val.length;
    int keep;

    // Find first nonzero byte
    for (keep = 0; keep < val.length && val[keep] == 0; keep++) {
      ;
    }

    // Only perform copy if necessary
    if (keep > 0) {
      int result[] = new int[val.length - keep];
      for (int i = 0; i < val.length - keep; i++) {
        result[i] = val[keep + i];
      }
      return result;
    }
    return val;
  }

  private int signInt() {
    return (int) (signum < 0 ? -1 : 0);
  }

  private static BigInteger valueOf(int val[]) {
    return (val[0] > 0 ? new BigInteger(val, 1) : new BigInteger(val));
  }

  private BigInteger(int[] magnitude, int signum) {
    this.signum = (magnitude.length == 0 ? 0 : signum);
    this.mag = magnitude;
  }

  private int firstNonzeroIntNum() {
    /*
     * Initialize firstNonzeroIntNum field the first time this method is
     * executed. This method depends on the atomicity of int modifies;
     * without this guarantee, it would have to be synchronized.
     */
    if (firstNonzeroIntNum == -2) {
      // Search for the first nonzero int
      int i;
      for (i = mag.length - 1; i >= 0 && mag[i] == 0; i--) {
        ;
      }
      firstNonzeroIntNum = mag.length - i - 1;
    }
    return firstNonzeroIntNum;
  }

  private int intLength() {
    return bitLength() / 32 + 1;
  }

  private int getInt(int n) {
    if (n < 0) {
      return 0;
    }
    if (n >= mag.length) {
      return signInt();
    }

    int magInt = mag[mag.length - n - 1];

    return (int) (signum >= 0 ? magInt :
                  (n <= firstNonzeroIntNum() ? -magInt : ~magInt));
  }

  public BigInteger remainder(
      BigInteger val) throws ArithmeticException {
    if (val.signum == 0) {
      throw new ArithmeticException("BigInteger: Divide by zero");
    }

    if (signum == 0) {
      return BigInteger.ZERO;
    }

    int[] res = new int[this.mag.length];

    System.arraycopy(this.mag, 0, res, 0, res.length);

    return new BigInteger(signum, remainder(res, val.mag));
  }

  /**
   * do a left shift - this returns a new array.
   */
  private int[] shiftLeft(
      int[] mag,
      int n) {
    int nInts = n >>> 5;
    int nBits = n & 0x1f;
    int magLen = mag.length;
    int newMag[] = null;

    if (nBits == 0) {
      newMag = new int[magLen + nInts];
      for (int i = 0; i < magLen; i++) {
        newMag[i] = mag[i];
      }
    }
    else {
      int i = 0;
      int nBits2 = 32 - nBits;
      int highBits = mag[0] >>> nBits2;

      if (highBits != 0) {
        newMag = new int[magLen + nInts + 1];
        newMag[i++] = highBits;
      }
      else {
        newMag = new int[magLen + nInts];
      }

      int m = mag[0];
      for (int j = 0; j < magLen - 1; j++) {
        int next = mag[j + 1];

        newMag[i++] = (m << nBits) | (next >>> nBits2);
        m = next;
      }

      newMag[i] = mag[magLen - 1] << nBits;
    }

    return newMag;
  }

  public BigInteger shiftLeft(
      int n) {
    if (signum == 0 || mag.length == 0) {
      return ZERO;
    }
    if (n == 0) {
      return this;
    }

    if (n < 0) {
      return shiftRight( -n);
    }

    return new BigInteger(signum, shiftLeft(mag, n));
  }

  /**
   * do a right shift - this does it in place.
   */
  private int[] shiftRight(
      int start,
      int[] mag,
      int n) {
    int nInts = (n >>> 5) + start;
    int nBits = n & 0x1f;
    int magLen = mag.length;

    if (nInts != start) {
      int delta = (nInts - start);

      for (int i = magLen - 1; i >= nInts; i--) {
        mag[i] = mag[i - delta];
      }
      for (int i = nInts - 1; i >= start; i--) {
        mag[i] = 0;
      }
    }

    if (nBits != 0) {
      int nBits2 = 32 - nBits;
      int m = mag[magLen - 1];

      for (int i = magLen - 1; i >= nInts + 1; i--) {
        int next = mag[i - 1];

        mag[i] = (m >>> nBits) | (next << nBits2);
        m = next;
      }

      mag[nInts] >>>= nBits;
    }

    return mag;
  }

  /**
   * do a right shift by one - this does it in place.
   */
  private int[] shiftRightOne(
      int start,
      int[] mag) {
    int magLen = mag.length;

    int m = mag[magLen - 1];

    for (int i = magLen - 1; i >= start + 1; i--) {
      int next = mag[i - 1];

      mag[i] = (m >>> 1) | (next << 31);
      m = next;
    }

    mag[start] >>>= 1;

    return mag;
  }

  public BigInteger shiftRight(
      int n) {
    if (n == 0) {
      return this;
    }

    if (n < 0) {
      return shiftLeft( -n);
    }

    if (n >= bitLength()) {
      return (this.signum < 0 ? valueOf( -1) : BigInteger.ZERO);
    }

    int[] res = new int[this.mag.length];

    System.arraycopy(this.mag, 0, res, 0, res.length);

    return new BigInteger(this.signum, shiftRight(0, res, n));
  }

  public int signum() {
    return signum;
  }

  /**
   * returns x = x - y - we assume x is >= y
   */
  private int[] subtract(
      int xStart,
      int[] x,
      int yStart,
      int[] y) {
    int iT = x.length - 1;
    int iV = y.length - 1;
    long m;
    int borrow = 0;

    do {
      m = ( ( (long) x[iT]) & IMASK) - ( ( (long) y[iV--]) & IMASK) + borrow;

      x[iT--] = (int) m;

      if (m < 0) {
        borrow = -1;
      }
      else {
        borrow = 0;
      }
    }
    while (iV >= yStart);

    while (iT >= xStart) {
      m = ( ( (long) x[iT]) & IMASK) + borrow;
      x[iT--] = (int) m;

      if (m < 0) {
        borrow = -1;
      }
      else {
        break;
      }
    }

    return x;
  }

  public BigInteger subtract(
      BigInteger val) {
    if (val.signum == 0 || val.mag.length == 0) {
      return this;
    }
    if (signum == 0 || mag.length == 0) {
      return val.negate();
    }
    if (val.signum < 0) {
      if (this.signum > 0) {
        return this.add(val.negate());
      }
    }
    else {
      if (this.signum < 0) {
        return this.add(val.negate());
      }
    }

    BigInteger bigun, littlun;
    int compare = compareTo(val);
    if (compare == 0) {
      return ZERO;
    }

    if (compare < 0) {
      bigun = val;
      littlun = this;
    }
    else {
      bigun = this;
      littlun = val;
    }

    int res[] = new int[bigun.mag.length];

    System.arraycopy(bigun.mag, 0, res, 0, res.length);

    return new BigInteger(this.signum * compare,
                          subtract(0, res, 0, littlun.mag));
  }

  public byte[] toByteArray() {
    int bitLength = bitLength();
    byte[] bytes = new byte[bitLength / 8 + 1];

    int bytesCopied = 4;
    int mag = 0;
    int ofs = this.mag.length - 1;
    int carry = 1;
    long lMag;
    for (int i = bytes.length - 1; i >= 0; i--) {
      if (bytesCopied == 4 && ofs >= 0) {
        if (signum < 0) {
          // we are dealing with a +ve number and we want a -ve one, so
          // invert the magnitude ints and add 1 (propagating the carry)
          // to make a 2's complement -ve number
          lMag = ~this.mag[ofs--] & IMASK;
          lMag += carry;
          if ( (lMag & ~IMASK) != 0) {
            carry = 1;
          }
          else {
            carry = 0;
          }
          mag = (int) (lMag & IMASK);
        }
        else {
          mag = this.mag[ofs--];
        }
        bytesCopied = 1;
      }
      else {
        mag >>>= 8;
        bytesCopied++;
      }

      bytes[i] = (byte) mag;
    }

    return bytes;
  }

  public String toString() {
    return toString(10);
  }

  public String toString(int rdx) {
    if (mag == null) {
      return "null";
    }
    else if (signum == 0) {
      return "0";
    }

    String s = new String();
    String h;

    if (rdx == 16) {
      for (int i = 0; i < mag.length; i++) {
        h = "0000000" + Integer.toHexString(mag[i]);
        h = h.substring(h.length() - 8);
        s = s + h;
      }
    }
    else {
      // This is algorithm 1a from chapter 4.4 in Seminumerical Algorithms, slow but it works
      Stack S = new Stack();
      BigInteger base = new BigInteger(Integer.toString(rdx, rdx), rdx);
      // The sign is handled separatly.
      // Notice however that for this to work, radix 16 _MUST_ be a special case,
      // unless we want to enter a recursion well. In their infinite wisdom, why did not
      // the Sun engineers made a c'tor for BigIntegers taking a BigInteger as parameter?
      // (Answer: Becuase Sun's BigIntger is clonable, something bouncycastle's isn't.)
      BigInteger u = new BigInteger(this.abs().toString(16), 16);
      BigInteger b;

      // For speed, maye these test should look directly a u.magnitude.length?
      while (!u.equals(BigInteger.ZERO)) {
        b = u.mod(base);
        if (b.equals(BigInteger.ZERO)) {
          S.push("0");
        }
        else {
          S.push(Integer.toString(b.mag[0], rdx));
        }
        u = u.divide(base);
      }
      // Then pop the stack
      while (!S.empty()) {
        s = s + S.pop();
      }
    }
    // Strip leading zeros.
    while (s.length() > 1 && s.charAt(0) == '0') {
      s = s.substring(1);

    }
    if (s.length() == 0) {
      s = "0";
    }
    else if (signum == -1) {
      s = "-" + s;

    }
    return s;
  }

  public static final BigInteger ZERO = new BigInteger(0, new byte[0]);
  public static final BigInteger ONE = valueOf(1);
  private static final BigInteger TWO = valueOf(2);

  public static BigInteger valueOf(
      long val) {
    if (val == 0) {
      return BigInteger.ZERO;
    }

    // store val into a byte array
    byte[] b = new byte[8];
    for (int i = 0; i < 8; i++) {
      b[7 - i] = (byte) val;
      val >>= 8;
    }

    return new BigInteger(b);
  }

  private int max(int a, int b) {
    if (a < b) {
      return b;
    }
    return a;
  }

  public int getLowestSetBit() {
    if (this.equals(ZERO)) {
      return -1;
    }

    int w = mag.length - 1;

    while (w >= 0) {
      if (mag[w] != 0) {
        break;
      }

      w--;
    }

    int b = 31;

    while (b > 0) {
      if ( (mag[w] << b) == 0x80000000) {
        break;
      }

      b--;
    }

    return ( ( (mag.length - 1) - w) * 32 + (31 - b));
  }

  public boolean testBit(
      int n) throws ArithmeticException {
    if (n < 0) {
      throw new ArithmeticException("Bit position must not be negative");
    }

    if ( (n / 32) >= mag.length) {
      return signum < 0;
    }

    return ( (mag[ (mag.length - 1) - n / 32] >> (n % 32)) & 1) > 0;
  }
}

⌨️ 快捷键说明

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