byte []到unsigned BigInteger?

gus*_*gus 24 c# arrays numeric biginteger

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

我能够在C#中将byte []转换为BigInteger ...
从我到目前为止的示例:

byte[] data;
byte[] result;
BigInteger biResult;

result = shaM.ComputeHash(data);
biResult = new BigInteger(result);
Run Code Online (Sandbox Code Playgroud)

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

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

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

编辑:感谢AakashM,Jon和Adam Robinson,在我需要的地方添加零字节.

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

Jon*_*Jon 34

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

注意:BigInteger构造函数期望数组采用little-endian顺序.如果您希望结果BigInteger具有特定值,请记住这一点.


小智 8

从 .NET Core 2.1 开始,BigInteger有一个带有可选参数的构造isUnsigned函数:

public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);
Run Code Online (Sandbox Code Playgroud)


Aak*_*shM 6

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

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

[...]

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

[...]

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


Ada*_*son 5

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

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

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

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


div*_*ira 5

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

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

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

这是执行此操作的代码:

byte[] byteArray;
// ...
var bigInteger = new BigInteger(byteArray.Concat(new byte[] { 0 }).ToArray());
Run Code Online (Sandbox Code Playgroud)