Java BigInteger与Mono .net BigInteger

我在.Net项目中使用BigInteger的单声道实现( 链接 )在Java中我使用java.math.BigInteger。

相同的代码在Java中产生不同的结果。

.Net代码

String inputBytes = "8E5BD77F0DCC30864634C134E28BFB42A149675A320786B616F4530708350D270353C30A40450325801B7AFED12BCCA274B8187072A89CC0CC3F95A24A8251243C1835898246F4D64CA3AC61DB841518F0E8FBC8996A40EB626153AE7F0BB87FD713FAC522719431428DE178E780A3FA45788A72C431926AED990E6DA268D2CC"; String modulus = "00e6b4b4511e0bd1b3d9c82ee189ba6d0c70b1466d94126f99a741af99a92701a789451742a357ddb61a4dea409965ec58dcaa5e30826de871b04700ed0fd46b1693446049734e8f95faba2bf9301347e63ba1771650e71982adef0cca6890b6f7baa7f5421a6533652f4b70c3c4270c480cf54cc06635f22901a42716d1dadf4f"; String exp = "010001"; BigInteger mModulus = new BigInteger(hexStringToByteArray(modulus)); BigInteger mExponent = new BigInteger(hexStringToByteArray(exp)); BigInteger input = new BigInteger(hexStringToByteArray(inputBytes)); BigInteger output = input.ModPow(mExponent, mModulus); Console.WriteLine("==RESULT==" + byteArray2Hex(output.GetBytes())); public static byte[] hexStringToByteArray(string hexString) { if (hexString.Length % 2 != 0) throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString)); byte[] HexAsBytes = new byte[hexString.Length / 2]; for (int index = 0; index < HexAsBytes.Length; index++) { string byteValue = hexString.Substring(index * 2, 2); HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } return HexAsBytes; } ==RESULT==01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003020300C06082A864886F70D02050500041009EB0D996BFC1EFA5675997712A1AB6E 

Java代码。 相同的inputBytes数组,相同的指数和模数,但结果不同。

 String inputBytes = "8E5BD77F0DCC30864634C134E28BFB42A149675A320786B616F4530708350D270353C30A40450325801B7AFED12BCCA274B8187072A89CC0CC3F95A24A8251243C1835898246F4D64CA3AC61DB841518F0E8FBC8996A40EB626153AE7F0BB87FD713FAC522719431428DE178E780A3FA45788A72C431926AED990E6DA268D2CC"; String modulus = "00e6b4b4511e0bd1b3d9c82ee189ba6d0c70b1466d94126f99a741af99a92701a789451742a357ddb61a4dea409965ec58dcaa5e30826de871b04700ed0fd46b1693446049734e8f95faba2bf9301347e63ba1771650e71982adef0cca6890b6f7baa7f5421a6533652f4b70c3c4270c480cf54cc06635f22901a42716d1dadf4f"; String exp = "010001"; BigInteger mModulus = new BigInteger(hexStringToByteArray(modulus)); BigInteger mExponent = new BigInteger(hexStringToByteArray(exp)); BigInteger input = new BigInteger(hexStringToByteArray(inputBytes)); BigInteger output = input.modPow(mExponent, mModulus); System.out.println("==RESULT==" + Utils.byteArray2Hex(output.getBytes())); public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } ==RESULT==6ce02bd9536ad76bcfd7633b6a2305ed98b43b0bb5fc2acbf984566f1ab35db02e651e9ed8793bf64b018455872b8ae3a06af082e8d680df407ea1e5df1336a19c6f3e116c6ff1940066396afa1de5633fad814fb42790b3af0e62e6dd53977f78794b2d105cdca9272f9c0feea119fe2c9691b6f6e21db3065fb25d840acea2 

我不明白为什么结果不同。

PS例如,如果我使用InputBytes

 String inputBytes = "242e35241b85fcfd75a53441ef9fc0941064c16f8e4555dabef5ce8ebc91400c6961b6b607e5dd762dbcabce51b11c8594e7d7183786c8e3c5300c7583c1871fc6f350b817682150b5cd0430ca9a2c3f8315b425c8fea0e7cc18187237ed47d29b082e7e7154888d5fb09f092a6dd5e2d3dac9df8de45837b708b5ae17f03e7f"; 

Java和.Net中的结果是一样的

 ==RESULT==01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003020300c06082a864886f70d02050500041046fd8e86a4833e7141cbe4718e8e92f7 

魔术在哪里?

来自java.math.BigInteger(byte[])的文档:

将包含BigInteger的二进制补码二进制表示的字节数组转换为BigInteger。 假设输入数组采用大端字节顺序:最重要的字节位于第0个元素中。

System.Numerics.BigInteger(byte[])的文档:

值数组中的各个字节应采用小端顺序,从最低位字节到最高位字节。

所以你可能只想尝试为你得到的一个值反转输入字节 – 你不清楚你应该反转哪个集合,因为我们不知道你试图表示什么值。 我建议在构造之后立即添加只是打印出正常的十进制表示的诊断 – 如果它们不相同,则其余的代码是无关紧要的。

我在inputBytes的开头添加了0位解决了我的问题。