Java vs C#BigInteger生成不同的值

时间:2017-08-02 20:56:06

标签: java c#

我在使用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

2 个答案:

答案 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()时第二次收到不同的价值。