Java与C#:BigInteger十六进制字符串产生不同的结果?

Ste*_*ger 2 c# java arrays biginteger endianness

题:

这段代码用Java:

BigInteger mod = new BigInteger("86f71688cdd2612ca117d1f54bdae029", 16);
Run Code Online (Sandbox Code Playgroud)

产生(在java中)数字

179399505810976971998364784462504058921
Run Code Online (Sandbox Code Playgroud)

但是,当我使用C#时,

BigInteger mod = BigInteger.Parse("86f71688cdd2612ca117d1f54bdae029", System.Globalization.NumberStyles.HexNumber); // base 16
Run Code Online (Sandbox Code Playgroud)

我没有得到相同的号码,我得到:

-160882861109961491465009822969264152535
Run Code Online (Sandbox Code Playgroud)

但是,当我直接从十进制创建数字时,它可以工作

BigInteger mod = BigInteger.Parse("179399505810976971998364784462504058921");
Run Code Online (Sandbox Code Playgroud)

我尝试在字节数组中转换十六进制字符串并将其反转,并从反转数组创建一个大整数,以防万一它是一个具有不同字节序的字节数组,但这没有帮助...

将Java-Code转换为C#时,我也遇到了以下问题:
Java

BigInteger k0 = new BigInteger(byte[]);
Run Code Online (Sandbox Code Playgroud)

要在C#中获得相同的数字,我必须反转数组,因为biginteger实现中的Endianness不同

C#等价物:

BigInteger k0 = new BigInteger(byte[].Reverse().ToArray());
Run Code Online (Sandbox Code Playgroud)

Luc*_*ski 7

以下是MSDN所说的内容BigInteger.Parse:

如果value是十六进制字符串,则Parse(String, NumberStyles)如果前两个十六进制数字大于或等于0x80,则该方法将值解释为使用二进制补码表示存储的负数.换句话说,该方法将值中第一个字节的最高位解释为符号位.要确保十六进制字符串被正确解释为正数,值中的第一个数字必须具有零值.例如,该方法将0x80解释为负值,但它将0x0800x0080解释为正值.

因此,0在解析的十六进制数字前面添加一个强制无符号解释.

对于Java和C#之间由字节数组表示的大整数的往返,我建议不要这样做,除非你真的需要.但是,这两种实现碰巧使用兼容的二进制补码表示,如果解决字节顺序问题.

MSDN说:

此方法返回的数组中的各个字节以little-endian顺序显示.也就是说,该值的低位字节在高位字节之前.数组的第一个BigInteger字节反映了值的前8位,第二个字节反映了后8位,依此类推.

Java文档说:

返回一个包含this的二进制补码表示的字节数组BigInteger.字节数组将采用big-endian字节顺序:最重要的字节位于第0个元素中.