我在使用Java生成与C#相同的BigInteger值时遇到了一些麻烦。在这两种语言中,我都是从一个字节数组创建BigIntegers,它们以相同的顺序保存相同的值。
Java BigInteger的创建方式如下:
BigInteger hashnum = new BigInteger(1, md.digest());
并产生: 79054595997078811232777738014361687045908459940911070866043475968067897954324
md.digest()以两种语言返回以下值: {-73,97,1,-64,23,38,69,95,107,122,119,-122,-99,-92,47,8,-118,70,119,98,64, - 1,-70,36}
我的C#代码:
添加0字节结束,但不反转字节数组
sbyte[] hashSBytes = md.digest();
if ((hashSBytes[hashSBytes.Length - 1] & 0x80) != 0)
{
Array.Resize<sbyte>(ref hashSBytes, hashSBytes.Length + 1);
}
BigInteger hashnum = new BigInteger((byte[])(object)hashSBytes);
BigInteger的值为92590942655695057524171612499701658178022831645290183610636811349839086444983
添加0字节AND反转字节数组
sbyte[] hashSBytes = md.digest();
Array.Reverse(hashSBytes);
if ((hashSBytes[hashSBytes.Length - 1] & 0x80) != 0)
{
Array.Resize<sbyte>(ref hashSBytes, hashSBytes.Length + 1);
}
BigInteger hashnum = new BigInteger((byte[])(object)hashSBytes);
BigInteger的值为82944647536515285715130977031103916663496217450446852247301410452203227690188
答案 0 :(得分:1)
在你继续抨击&#34; SO点纳粹&#34;在SitePoint上,我认为你在其他地方做错了什么。当你将大整数作为字符串并在JAVA和C#中解析它时,当你投射到一个字节数组时,你会得到完全相同的结果。
00,AE,C7,50,D1,1F,EE,E9,F1,62,71,92,2F,BA,F5,A9,BE,14,2F,62,01,9E,F8,D7,20,F8,58,94,00,70,88,90,14
你是对的,在C#中反转,但仍然是相同的。
<强> C#强>
var bi = BigInteger.Parse("79054595997078811232777738014361687045908459940911070866043475968067897954324");
Console.WriteLine(
String.Join(",",
bi.ToByteArray().Reverse().Select(s=>s.ToString("X2"))));
<强> JAVA 强>
import java.math.BigInteger;
public class BigIntSample {
public static void main(String[] args) {
// TODO Auto-generated method stub
BigInteger bi = new BigInteger("79054595997078811232777738014361687045908459940911070866043475968067897954324");
byte[] bytes = bi.toByteArray();
System.out.println(byteArrayToHex(bytes));
}
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for (byte b : a)
sb.append(String.format("%02X", b).concat(","));
return sb.toString();
}
}
我认为主要的问题是在C#中你正在处理sbyte
s,有符号字节,其含义与byte
s完全不同。我可能错了,但绝对不是纳粹&#34;。
<强>和平强>
答案 1 :(得分:0)
我的C#代码一直正常运行。我试图匹配的java结果是错误的。 md.digest()在java代码中被调用了2次,但它是非静态的,并且没有被重置。第一个调用甚至不应该在那里,它只是用于调试,以便我可以将它分配给属性并在调试器中查看值,因为BigInteger构造函数直接使用md.digest()。在我的调试行调用该方法之后,我无法在此非静态类中重置数组,所以即使我在此行的调试器中看到相同的值,当它实际创建BigInteger并调用md.digest()时第二次收到不同的价值。