动机: 我想将哈希值(MD5 / SHA1等)转换为十进制整数,以便在Code128C中生成条形码。 为简单起见,我更喜欢所有得到的(大)数字为正数。
我能够在C#...中转换byte []到BigInteger 从我到目前为止的样本:
byte[] data;
byte[] result;
BigInteger biResult;
result = shaM.ComputeHash(data);
biResult = new BigInteger(result);
但是(这里生锈的CS)我更正确的是,字节数组总是可以用两种方式解释: 答:作为签名号码 B:作为无符号数字
是否可以从C#中的byte []创建一个UNSIGNED BigInteger?
我应该简单地在字节[]的前面添加一个0x00(零字节)吗?
编辑: 感谢AakashM,Jon和Adam Robinson,实现了我需要的零字节。\
EDIT2: 我应该做的主要是阅读BigInteger(byte [])构造函数的详细文档,然后我会看到有关如何通过附加零字节限制为正数的部分。
答案 0 :(得分:34)
remarks for the BigInteger
constructor状态,如果您将BigInteger
字节附加到数组的末尾,则可以确保从byte[]
创建的任何00
都是无符号的之前调用构造函数。
注意:BigInteger
构造函数需要数组采用little-endian顺序。如果您希望结果BigInteger
具有特定值,请记住这一点。
答案 1 :(得分:6)
审核the documentation for the relevant BigInteger
constructor,我们看到:
值中的各个字节 数组应该是 little-endian 顺序,从最低位字节到 最高位字节
[...]
构造函数期望积极 要使用的字节数组中的值 符号和幅度表示,和 负值使用两个 补充表示。 其他 单词,如果是最高位的 设置值中的最高位字节, 得到的BigInteger值是 负即可。取决于来源 字节数组,这可能会导致a 积极的价值被误解为 负值。
[...]
要防止 积极的价值观 被误解为负值,你 可以为结束添加零字节值 数组。
答案 2 :(得分:5)
但是(这里生锈的CS)我更正确的是,字节数组总是可以用两种方式解释:A:作为有符号数B:作为无符号数
更正确的是,所有数字(由于存储在计算机中)基本上是一系列字节,这是字节数组。说字节数组总是可以解释为特定数字类型的有符号或无符号版本,因为并非所有数字类型都有签名和无符号版本。浮点类型通常只有签名版本(没有udouble
或ufloat
),并且在此特定实例中,没有BigInteger
的无符号版本。
所以,换句话说,不,这是不可能的,但由于BigInteger
可以代表一个任意大的整数值,你不会因为被签名而失去任何范围。
关于第二个问题,您需要将0x00
附加到数组的 end ,因为BigInteger
constructor以little-endian字节顺序解析值。
答案 3 :(得分:5)
正如其他答案所指出的那样,你应该在数组末尾添加一个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 :(得分:2)
另一种方法是使用您的字节数组创建BigInteger
,然后使用Abs
(相当于Math.Abs
)使其成为绝对值:
var bi = new BigInteger(result);
var biPositive = BigInteger.Abs(bi1);
从技术上讲,如果Abs
为否定,您只需使用bi
(例如,如果bi.Sign == -1
)
答案 5 :(得分:0)
截至本文发布之日,BigInteger的ctor现在具有可选参数“ isUnsigned”。 (已针对核心.Net验证)