Java与C#:BigInteger十六进制字符串会产生不同的结果
本文关键字:结果 字符串 BigInteger 十六进制 Java | 更新日期: 2023-09-27 18:11:14
问题:
这个Java代码:
BigInteger mod = new BigInteger("86f71688cdd2612ca117d1f54bdae029", 16);
产生(在java中(数字
179399505810976971998364784462504058921
然而,当我使用C#时,
BigInteger mod = BigInteger.Parse("86f71688cdd2612ca117d1f54bdae029", System.Globalization.NumberStyles.HexNumber); // base 16
我没有得到相同的号码,我得到了:
-160882861109961491465009822969264152535
然而,当我直接从十进制创建数字时,它可以
BigInteger mod = BigInteger.Parse("179399505810976971998364784462504058921");
我尝试在字节数组中转换十六进制字符串并反转它,并从反转的数组中创建一个biginteger,以防它是一个具有不同endianness的字节数组,但这没有帮助。。。
在将Java代码转换为C#时,我还遇到了以下问题:
Java
BigInteger k0 = new BigInteger(byte[]);
为了在C#中获得相同的数字,我必须反转数组,因为在大整数实现中的Endianness不同
C#等价物:
BigInteger k0 = new BigInteger(byte[].Reverse().ToArray());
以下是MSDN对BigInteger.Parse
:的介绍
如果值是十六进制字符串,则如果值的前两个十六进制数字大于或等于0x80,则
Parse(String, NumberStyles)
方法将值解释为通过使用二的补码表示存储的负数。换句话说,该方法将值中第一个字节的最高阶位解释为符号位。为了确保十六进制字符串被正确解释为正数,值中的第一个数字必须为零。例如,该方法将0x80解释为负值,但将0x080x0080>解释为正值。
因此,在解析的十六进制数字前面添加一个0
,以强制执行无符号解释。
至于Java和C#之间由字节数组表示的大整数的往返,我建议不要这样做,除非你真的必须这样做。但如果你修复了endianness问题,两个实现都会使用兼容的二进制补码表示。
MSDN表示:
此方法返回的数组中的各个字节以little-endian的顺序出现。也就是说,值的低阶字节在高阶字节之前。数组的第一个字节反映
BigInteger
值的前八位,第二个字节反映接下来的八位,依此类推
Java文档说:
返回一个字节数组,该数组包含此
BigInteger
的二进制补码表示形式。字节数组将按big-endian字节顺序排列:最高有效字节在第零个元素中。