byte 到unsigned BigInteger?

动机:为了在Code128C中制作条形码,我想将哈希值(MD5 / SHA1等)转换为十进制整数。 为简单起见,我更喜欢所有得到的(大)数字为正数。

我能够在C#中将byte []转换为BigInteger …
从我到目前为止的样本:

byte[] data; byte[] result; BigInteger biResult; result = shaM.ComputeHash(data); biResult = new BigInteger(result); 

但是(这里生锈的CS)我更正确的是,字节数组总是可以用两种方式解释:A:作为有符号数B:作为无符号数

是否可以从C#中的byte []创建一个UNSIGNED BigInteger?

我应该简单地在字节[]的前面加一个0x00(零字节)吗?

编辑:感谢AakashM,Jon和Adam Robinson,在我需要的时候添加零字节。

编辑2:我应该做的主要是阅读BigInteger(byte [])构造函数的详细文档,然后我会看到有关如何通过附加零字节限制为正数的部分。

BigInteger构造函数的备注表明,如果在调用构造函数之前将00字节附加到数组的末尾,则可以确保从byte[]创建的任何BigInteger都是无符号的。

注意: BigInteger构造函数要求数组采用little-endian顺序。 如果您希望生成的BigInteger具有特定值,请记住这一点。

但是(这里生锈的CS)我更正确的是,字节数组总是可以用两种方式解释:A:作为有符号数B:作为无符号数

更正确的是,所有数字(由于存储在计算机中)基本上是一系列字节,这是字节数组。 说字节数组总是可以解释为特定数字类型的有符号或无符号版本,因为并非所有数字类型都有签名和无符号版本。 浮点类型通常只有签名版本(没有udoubleufloat ),并且在这个特定实例中,没有未签名的BigInteger版本。

所以,换句话说,不,这是不可能的,但由于BigInteger可以代表一个任意大的整数值,你不会因为它被签名而失去任何范围。

至于你的第二个问题,你需要将0x00附加到数组的结尾 ,因为BigInteger构造函数以little-endian字节顺序解析值。

检查相关BigInteger构造函数的文档 ,我们看到:

值数组中的各个字节应采用小端顺序,从最低位字节到最高位字节

[…]

构造函数期望字节数组中的正值使用符号和幅度表示,而负值则使用2的补码表示。 换句话说,如果设置了值中最高位字节的最高位,则生成的BigInteger值为负 。 根据字节数组的来源,这可能会导致正值被误解为负值。

[…]

要防止将正值误解为负值,可以在数组末尾添加零字节值。

正如其他答案所指出的那样,您应该在数组的末尾添加一个00字节,以确保生成的BigInteger为正数。

根据BigInteger结构(System.Numerics)MSDN文档

防止BigInteger(Byte [])构造函数将负值的二进制补码表示与正值的符号和幅度表示混淆,正值通常是字节数组中最后一个字节的最高位set应包含一个值为0的附加字节。

这是代码:

 byte[] byteArray; // ... var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray()); 

另一种方法是使用您的字节数组创建一个BigInteger ,然后使用Abs (相当于Math.Abs )使其成为绝对值:

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

从技术上讲,如果bi是负数,你只需要使用Abs (例如,如果bi.Sign == -1