byte[]转换为无符号BigInteger

本文关键字:无符号 BigInteger 转换 byte | 更新日期: 2023-09-27 17:50:17

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

我能够在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[](构造函数的详细文档,然后我会看到关于如何通过附加零字节来限制为正数的部分。

byte[]转换为无符号BigInteger

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

注意:BigInteger构造函数希望数组按小端序排列。如果希望生成的BigInteger具有特定值,请记住这一点。

自.NET Core 2.1以来,BigInteger有一个带有可选参数isUnsigned:的构造函数

public BigInteger (ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false);

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

值中的单个字节数组应在小端序中顺序,从最低顺序字节到最高阶字节

[…]

构造函数要求为正数要使用的字节数组中的值符号和幅度表示,以及负值使用两个补码表示在其他单词,如果设置值中的最高阶字节,得到的BigInteger值为阴性。取决于字节数组,这可能会导致正值被误解为负值。

[…]

防止存在的正值被误解为负值,你可以将零字节值添加到结尾数组的。

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

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

为了防止BigInteger(Byte[](构造函数将负值的补码表示与正值的符号和幅度表示混淆,通常设置字节数组中最后一个字节的最高有效位的正值应包括一个值为0的附加字节。

下面是代码:

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

但是(这里是生疏的CS(我对字节数组总是可以用两种方式解释吗:a:作为有符号的数字B:作为无符号的数字

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

换言之,不,这是不可能的,但由于BigInteger可以表示任意大的整数值,因此不会因为其有符号而丢失任何范围。

至于第二个问题,您需要将0x00附加到数组的endend,因为BigInteger构造函数以小端字节顺序解析值。