问题描述
|
动机:
我想将哈希(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 [])构造函数的详细文档,然后我将看到有关如何通过附加零字节来限制为正数的部分。
解决方法
关于“ 1”构造函数的说明指出,如果在调用构造函数之前在数组末尾附加“ 4”字节,则可以确保从“ 3”创建的任何“ 1”都未签名。
注意:
BigInteger
构造函数期望该数组采用小尾数顺序。如果您期望结果ѭ1具有特定值,请记住这一点。
,检查有关BigInteger
构造函数的文档,我们看到:
值中的各个字节
数组应为小端
顺序,从最低顺序字节到
最高位字节
[...]
建设者期望积极
字节数组中使用的值
符号和幅度表示,以及
负值使用二
补码表示。其他
字,如果
设置值的最高位字节,
得到的BigInteger值是
负。取决于来源
字节数组,这可能会导致
正值被误解为
负值。
[...]
阻止
来自的积极价值
被误解为负值,你
可以在末尾添加一个零字节的值
的数组。
, 但是(这里是生锈的CS)我是否可以始终以两种方式解释字节数组:A:作为有符号数B:作为无符号数
更正确的是,所有数字(由于存储在计算机中)基本上都是一系列字节,这就是字节数组。并非总是可以将字节数组解释为特定数字类型的带符号或无符号版本,因为并非所有数字类型都具有带符号和无符号版本。浮点类型通常只有带符号的版本(没有udouble
或ufloat
),在这种情况下,没有un1 un的无符号版本。
因此,换句话说,不,这是不可能的,但是由于BigInteger
可以表示任意大的整数值,因此您不会因其带符号而失去任何范围。
关于第二个问题,由于BigInteger
构造函数以Little-endian字节顺序分析值,因此您需要在数组的末尾附加0x00
。
,正如其他答案所指出的那样,您应该在数组末尾附加一个00字节,以确保结果BigInteger为正。
根据BigInteger结构(System.Numerics)MSDN文档
为了防止BigInteger(Byte [])构造函数将负值的二进制补码表示与正值的正负号和幅值表示混淆,正值表示字节数组中最后一个字节的最高有效位通常设置为应包含一个值为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
为负数时(例如,如果bi.Sign == -1
),才需要使用Abs
。
,自发布之日起,BigInteger的ctor现在具有可选参数\“ isUnsigned \”。 (已针对核心.Net验证)