0N/A/*
2362N/A * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.util;
0N/A
0N/Aimport java.math.BigInteger;
0N/A
0N/A
0N/A/**
0N/A * A low-overhead arbitrary-precision <em>unsigned</em> integer.
0N/A * This is intended for use with ASN.1 parsing, and printing of
0N/A * such parsed values. Convert to "BigInteger" if you need to do
0N/A * arbitrary precision arithmetic, rather than just represent
0N/A * the number as a wrapped array of bytes.
0N/A *
0N/A * <P><em><b>NOTE:</b> This class may eventually disappear, to
0N/A * be supplanted by big-endian byte arrays which hold both signed
0N/A * and unsigned arbitrary-precision integers.</em>
0N/A *
0N/A * @author David Brownell
0N/A */
0N/Apublic final class BigInt {
0N/A
0N/A // Big endian -- MSB first.
0N/A private byte[] places;
0N/A
0N/A /**
0N/A * Constructs a "Big" integer from a set of (big-endian) bytes.
0N/A * Leading zeroes should be stripped off.
0N/A *
0N/A * @param data a sequence of bytes, most significant bytes/digits
0N/A * first. CONSUMED.
0N/A */
0N/A public BigInt(byte[] data) { places = data.clone(); }
0N/A
0N/A /**
0N/A * Constructs a "Big" integer from a "BigInteger", which must be
0N/A * positive (or zero) in value.
0N/A */
0N/A public BigInt(BigInteger i) {
0N/A byte[] temp = i.toByteArray();
0N/A
0N/A if ((temp[0] & 0x80) != 0)
0N/A throw new IllegalArgumentException("negative BigInteger");
0N/A
0N/A // XXX we assume exactly _one_ sign byte is used...
0N/A
0N/A if (temp[0] != 0)
0N/A places = temp;
0N/A else {
0N/A places = new byte[temp.length - 1];
0N/A for (int j = 1; j < temp.length; j++)
0N/A places[j - 1] = temp[j];
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Constructs a "Big" integer from a normal Java integer.
0N/A *
0N/A * @param i the java primitive integer
0N/A */
0N/A public BigInt(int i) {
0N/A if (i < (1 << 8)) {
0N/A places = new byte[1];
0N/A places[0] = (byte) i;
0N/A } else if (i < (1 << 16)) {
0N/A places = new byte[2];
0N/A places[0] = (byte) (i >> 8);
0N/A places[1] = (byte) i;
0N/A } else if (i < (1 << 24)) {
0N/A places = new byte[3];
0N/A places[0] = (byte) (i >> 16);
0N/A places[1] = (byte) (i >> 8);
0N/A places[2] = (byte) i;
0N/A } else {
0N/A places = new byte[4];
0N/A places[0] = (byte) (i >> 24);
0N/A places[1] = (byte) (i >> 16);
0N/A places[2] = (byte) (i >> 8);
0N/A places[3] = (byte) i;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Converts the "big" integer to a java primitive integer.
0N/A *
0N/A * @excpet NumberFormatException if 32 bits is insufficient.
0N/A */
0N/A public int toInt() {
0N/A if (places.length > 4)
0N/A throw new NumberFormatException("BigInt.toLong, too big");
0N/A int retval = 0, i = 0;
0N/A for (; i < places.length; i++)
0N/A retval = (retval << 8) + ((int)places[i] & 0xff);
0N/A return retval;
0N/A }
0N/A
0N/A /**
0N/A * Returns a hexadecimal printed representation. The value is
0N/A * formatted to fit on lines of at least 75 characters, with
0N/A * embedded newlines. Words are separated for readability,
0N/A * with eight words (32 bytes) per line.
0N/A */
0N/A public String toString() { return hexify(); }
0N/A
0N/A /**
0N/A * Returns a BigInteger value which supports many arithmetic
0N/A * operations. Assumes negative values will never occur.
0N/A */
0N/A public BigInteger toBigInteger()
0N/A { return new BigInteger(1, places); }
0N/A
0N/A /**
0N/A * Returns the data as a byte array. The most significant bit
0N/A * of the array is bit zero (as in <code>java.math.BigInteger</code>).
0N/A */
0N/A public byte[] toByteArray() { return places.clone(); }
0N/A
0N/A private static final String digits = "0123456789abcdef";
0N/A private String hexify() {
0N/A if (places.length == 0)
0N/A return " 0 ";
0N/A
0N/A StringBuffer buf = new StringBuffer(places.length * 2);
0N/A buf.append(" "); // four spaces
0N/A for (int i = 0; i < places.length; i++) {
0N/A buf.append(digits.charAt((places[i] >> 4) & 0x0f));
0N/A buf.append(digits.charAt(places[i] & 0x0f));
0N/A if (((i + 1) % 32) == 0) {
0N/A if ((i + 1) != places.length)
0N/A buf.append("\n "); // line after four words
0N/A } else if (((i + 1) % 4) == 0)
0N/A buf.append(' '); // space between words
0N/A }
0N/A return buf.toString();
0N/A }
0N/A
0N/A /**
0N/A * Returns true iff the parameter is a numerically equivalent
0N/A * BigInt.
0N/A *
0N/A * @param other the object being compared with this one.
0N/A */
0N/A public boolean equals(Object other) {
0N/A if (other instanceof BigInt)
0N/A return equals((BigInt) other);
0N/A return false;
0N/A }
0N/A
0N/A /**
0N/A * Returns true iff the parameter is numerically equivalent.
0N/A *
0N/A * @param other the BigInt being compared with this one.
0N/A */
0N/A public boolean equals(BigInt other) {
0N/A if (this == other)
0N/A return true;
0N/A
0N/A byte[] otherPlaces = other.toByteArray();
0N/A if (places.length != otherPlaces.length)
0N/A return false;
0N/A for (int i = 0; i < places.length; i++)
0N/A if (places[i] != otherPlaces[i])
0N/A return false;
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * Returns a hashcode for this BigInt.
0N/A *
0N/A * @return a hashcode for this BigInt.
0N/A */
0N/A public int hashCode() {
0N/A return hexify().hashCode();
0N/A }
0N/A}