byte[] to unsigned BigInteger?

后端 未结 6 756
逝去的感伤
逝去的感伤 2020-12-06 09:21

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 al

相关标签:
6条回答
  • 2020-12-06 09:46

    But (rusty CS here) am I correct that a byte array can always be interpreted in two ways: A: as a signed number B: as an unsigned number

    What's more correct is that all numbers (by virtue of being stored in the computer) are basically a series of bytes, which is what a byte array is. It's not true to say that a byte array can always be interpreted as a signed or unsigned version of a particular numeric type, as not all numeric types have signed and unsigned versions. Floating point types generally only have signed versions (there's no udouble or ufloat), and, in this particular instance, there is no unsigned version of BigInteger.

    So, in other words, no, it's not possible, but since BigInteger can represent an arbitrarily large integer value, you're not losing any range by virtue of its being signed.

    As to your second question, you would need to append 0x00 to end end of the array, as the BigInteger constructor parses the values in little-endian byte order.

    0 讨论(0)
  • 2020-12-06 09:51

    As of the date of this post the ctor for BigInteger now has an optional parameter "isUnsigned". (verified for core .Net)

    0 讨论(0)
  • 2020-12-06 09:54

    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());
    
    0 讨论(0)
  • 2020-12-06 09:57

    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.

    0 讨论(0)
  • 2020-12-06 10:03

    An alternative is to create a BigInteger using your byte array, then use Abs (equivalent to Math.Abs) to make it an absolute value:

    var bi = new BigInteger(result);
    var biPositive = BigInteger.Abs(bi1);
    

    Technically, you only need to use Abs if bi is negative (e.g. if bi.Sign == -1)

    0 讨论(0)
  • 2020-12-06 10:04

    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.

    0 讨论(0)
提交回复
热议问题