byte[] 到无符号 BigInteger?

Posted

技术标签:

【中文标题】byte[] 到无符号 BigInteger?【英文标题】:byte[] to unsigned BigInteger? 【发布时间】:2011-08-04 16:27:57 【问题描述】:

动机: 我想将哈希(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?

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

编辑: 感谢 AakashM、Jon 和 Adam Robinson,附加零字节实现了我的需要。

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

【问题讨论】:

你应该标记一个接受的答案 【参考方案1】:

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

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

【讨论】:

如果您使用的是现代版本的 .NET(不是 .NET Framework),请参阅Mike K's answer 以获得更好的解决方案。【参考方案2】:

检查the documentation for the relevant BigInteger constructor,我们看到:

值中的各个字节 数组应该是 little-endian 顺序,从最低字节到 最高字节

[...]

构造函数期望正数 要使用的字节数组中的值 符号和大小表示,以及 使用二的负值 补表示。 在其他 的话,如果的最高位 设置值中的最高字节, 结果 BigInteger 值为 否定。根据来源 字节数组,这可能会导致 正值被误解为 负值。

[...]

为了防止 积极的价值观 被误解为负值,你 可以在结尾添加一个零字节的值 数组。

【讨论】:

【参考方案3】:

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

根据the BigInteger Structure (System.Numerics) MSDN Documentation

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

下面是代码:

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

【讨论】:

【参考方案4】:

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

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

因此,换句话说,不,这是不可能的,但是由于BigInteger 可以表示任意大的整数值,因此您不会因为它被签名而丢失任何范围。

至于您的第二个问题,您需要将 0x00 附加到数组的末尾 end,因为 BigInteger constructor 以 little-endian 字节顺序解析值。

【讨论】:

【参考方案5】:

从 .NET Core 2.1 开始,BigInteger 有一个 constructor 和一个可选参数 isUnsigned

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

【讨论】:

以上是关于byte[] 到无符号 BigInteger?的主要内容,如果未能解决你的问题,请参考以下文章

从文件中读取文本到无符号字符数组

如何在 Rust 中将有符号整数添加到无符号整数,检查无符号溢出?

一元减号和有符号到无符号的转换

字符到无符号字符

从有符号/无符号字符到无符号/有符号整数类型转换的 IA32 汇编代码

C中的有符号到无符号转换 - 它总是安全的吗?