Motivation: I would like to convert hashes (MD5/SHA1 etc) into decimal integers for the purpose of making barcodes in Code128C. For simplicity, I prefer all the resulting (large) numbers to be positive.
I am able to convert byte[] to BigInteger in C#...
Sample from what I have so far:
byte[] data;
byte[] result;
BigInteger biResult;
result = shaM.ComputeHash(data);
biResult = new BigInteger(result);
But (rusty CS here) am I correct that a byte array can always be interpreted in two ways:
Is it possible to make an UNSIGNED BigInteger from a byte[] in C#?
Should I simply prepend a 0x00 (zero byte) to the front of the byte[]?
EDIT: Thank you to AakashM, Jon and Adam Robinson, appending a zero byte achieved what I needed.
EDIT2: The main thing I should have done was to read the detailed doc of the BigInteger(byte[]) constructor, then I would have seen the sections about how to restrict to positive numbers by appending the zero byte.
Description. A large integer. The signed range is -9223372036854775808 to 9223372036854775807 . The unsigned range is 0 to 18446744073709551615 . If a column has been set to ZEROFILL, all values will be prepended by zeros so that the BIGINT value contains a number of M digits.
Java doesn't have unsigned bytes (0 to 255). To make an unsigned byte, we can cast the byte into an int and mask (bitwise and) the new int with a 0xff to get the last 8 bits or prevent sign extension.
The BigInteger type is an immutable type that represents an arbitrarily large integer whose value in theory has no upper or lower bounds. The members of the BigInteger type closely parallel those of other integral types (the Byte, Int16, Int32, Int64, SByte, UInt16, UInt32, and UInt64 types).
Problems arise when integers are type casted to bytes. This is a narrowing primitive conversion, for integers it works by copying the less significant bits. In this case, the eight less significant bits from the integer are copied to the byte. If the copied value is above 127 we end up with a negative byte value.
The remarks for the BigInteger
constructor state that you can make sure any BigInteger
created from a byte[]
is unsigned if you append a 00
byte to the end of the array before calling the constructor.
Note: the BigInteger
constructor expects the array to be in little-endian order. Keep that in mind if you expect the resulting BigInteger
to have a particular value.
Examining the documentation for the relevant BigInteger
constructor, we see:
The individual bytes in the value array should be in little-endian order, from lowest-order byte to highest-order byte
[...]
The constructor expects positive values in the byte array to use sign-and-magnitude representation, and negative values to use two's complement representation. In other words, if the highest-order bit of the highest-order byte in value is set, the resulting BigInteger value is negative. Depending on the source of the byte array, this may cause a positive value to be misinterpreted as a negative value.
[...]
To prevent positive values from being misinterpreted as negative values, you can add a zero-byte value to the end of the array.
Since .NET Core 2.1, BigInteger
has a constructor with an optional parameter isUnsigned
:
public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);
As other answers have pointed out, you should append a 00 byte to the end of the array to ensure the resulting BigInteger is positive.
According to the the BigInteger Structure (System.Numerics) MSDN Documentation
To prevent the BigInteger(Byte[]) constructor from confusing the two's complement representation of a negative value with the sign and magnitude representation of a positive value, positive values in which the most significant bit of the last byte in the byte array would ordinarily be set should include an additional byte whose value is 0.
Here's code to do it:
byte[] byteArray;
// ...
var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With