BigInteger in Java and C#
I was working on a task where I need to generate a BigInteger number in C# which should be the same if generated in Java. Two libraries – in Java and C# should generate BigInteger and they should be the same.
BigInteger in Java and C# are different so you can't use something like this
java.math.BigInteger(byte[]) System.Numerics.BigInteger(byte[]):
For Java
Translates a byte array containing the two's-complement binary representation of a BigInteger into a
BigInteger. The input array is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element.
And C#
The individual bytes in the value array should be in little-endian order, from lowest-order byte to highest-order byte.
First of all what is big-endian and little-endian? These are terms that describe the order in which a sequence of bytes are stored in the computer memory. Big-endian is an order in which the most significant value in the sequence is stored first, at the lowest storage address. In little-endian the less significant value in the sequence is store first.
For example, in a big-endian system the hexadecimal 3A86 will be stored as 3A86. If 3A is stored at the address 1000 then 86 will be stored at the address 1001. In a little-endian computer the same number will be stored as 863A – 86 at address 1000 and 3A at address 1001.
The same number in binary format
00000000 00000000 00111010 10000110
Will be stored as follows
Address | Big-endian | Little-endian |
1000 | 00000000 | 10000110 |
1001 | 00000000 | 00111010 |
1002 | 00111010 | 00000000 |
1003 | 10000110 | 00000000 |
What we need to do is provide the byte array in big-endian so the behaviour will be the same as in Java.
If we have variable data
byte[] data = {1, 65, 30, 47};
Will transform into big-endian by reversing bytes.
byte[] reverseData = data.Reverse().ToArray();
The output array will be
{47, 30, 65, 1}
and provide it to the BigInteger constructor
new BigInteger(reverseData);
NOTE
If you try to compare the variable data in Java and C# (when you get the value from another operation, file load, hashing, etc.) by printing them, then they might be different. The reason for this is that Java bytes are signed but C# bytes are unsigned. A Java byte equivalent to C# is sbyte.
This conversion will do the trick
sbyte[] dataCnv = (sbyte[]) (Array) data;