Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigInteger to byte[]

I need to convert a Java BigInteger instance to its value in bytes. From the API, I get this method toByteArray(), that returns a byte[] containing the two's-complement representation of this BigInteger.

Since all my numbers are positive 128 bits (16 bytes) integer, I don't need the 2's-complement form that give me 128 bits + sign bit (129 bits)...

Is there a way to get the standard (without the 2's-complement form) representation directly from a BigInteger?

If not, how can I right shift the whole byte[17] array to lose the sign bit in order to get a byte[16] array?

like image 954
Kami Avatar asked Dec 10 '10 10:12

Kami


People also ask

How many bytes is a BigInteger?

That's a total of 20 bytes + the integer array.

How do I convert BigInteger to integer?

math. BigInteger. intValue() converts this BigInteger to an integer value. If the value returned by this function is too big to fit into integer value, then it will return only the low-order 32 bits.

What is BigInteger one in Java?

BigInteger provides analogues to all of Java's primitive integer operators, and all relevant methods from java. lang. Math. Additionally, BigInteger provides operations for modular arithmetic, GCD calculation, primality testing, prime generation, bit manipulation, and a few other miscellaneous operations.


Video Answer


2 Answers

You don't have to shift at all. The sign bit is the most significant (= leftmost) bit of your byte array. Since you know your numbers will always be positive, it is guaranteed to be 0. However, the array as a whole is right-aligned.

So there are two cases: your left-most byte is 0x00 or not. If it is 0x00 you can safely drop it:

byte[] array = bigInteger.toByteArray();
if (array[0] == 0) {
    byte[] tmp = new byte[array.length - 1];
    System.arraycopy(array, 1, tmp, 0, tmp.length);
    array = tmp;
}

If it is not 0, then you cannot drop it - but your array will already be in the representation you want, so you don't have to do anything.

The above code should work for both cases.

like image 186
Thomas Avatar answered Sep 28 '22 07:09

Thomas


The first (most significant) byte in the byte array may not just contain the sign bit, but normal bits too.

E.g. this BigInteger:

new BigInteger("512")
    .add(new BigInteger("16"))
    .add(new BigInteger("1"));

has this bit pattern: 00000010 00010001

Which is to say the top byte (with the sign bit) also has 'normal' bits as you'd expect.

So, what do you want to get back?

00000010 00010001 (what you have) or
00000100 0010001? or
10000100 01??????
like image 42
daveb Avatar answered Sep 28 '22 07:09

daveb