2011-12-01 27 views
0

我需要帮助将此代码从C#转换为Java。如何将C#中的校验和代码转换为Java?

public static ulong GetChecksum(byte[] data) 
    { 
     ulong sum = 0; 
     foreach (var item in data) 
      sum += item; 

     return ulong.MaxValue - sum + 1; 
    } 

Java版本将返回long,而不是ulong。

编辑:我还没有尝试过任何东西,因为我不知道如何处理最后一行ulong.MaxValue。基本上,我最终得到的结果是在C#中生成与(getChecksum(buffer))长度相同的数字,与java中的getChecksum(buffer)相同。 我对java很陌生,这就是为什么我要问这个问题。

编辑2:这是最终的解决方案。许多有用的评论。感谢你们。

public static byte[] getChecksum(byte[] data) { 
     BigInteger sum = BigInteger.ZERO; 
     for (byte s : data) 
      sum = sum.add(BigInteger.valueOf((long) ((char) s & 0xFF))); 

     return new BigInteger("FFFFFFFFFFFFFFFF", 16).subtract(sum).add(BigInteger.ONE).toByteArray(); 
    } 

编辑2:太糟糕了,这个问题被降低了。它有许多有用的评论。

+2

你试过了吗? –

+0

你有什么问题? Java和C#已经很相似了,这是一个非常简单的函数。 – mpen

+0

'byte'在C#中是无符号的,那么在Java中使用什么类型的适当类型呢? C#中的'foreach'循环在Java中不存在,替换它的适当构造是什么?你将如何处理C#返回一个无符号类型,但在Java中返回一个签名类型?你担心溢出吗? (这些是您应该考虑的问题,并且使用Google进行搜索,而不是要求陌生人编写您的转换。) –

回答

1

由于Java不抛出算术溢出错误,你应该能够做一些事情,如:

long sum = 0; 
for (byte b : data) 
    sum += (long) b; 

return sum; 

回报是基于要完全相同的结果的假设简化(二进制,而不是在C#中)。 ulong.MaxValue是64位的1,它是带符号长的-1,取消了“+1”。

编辑:我在这里说了谎。结果应该是合乎逻辑的-sum,这是由于默认的两个恭维实现,所以不能轻易完成。您应该考虑BigInteger解决方案。编辑2:由于有符号减法行为不均匀,因此无法简单模拟无符号运算ulong.MaxValue - sum。我建议你做的是:

long sum = 0; 
for (byte b : data) 
    sum += ((long) b) & 0xFFL; // To prevent sign-expansion. Sorry, I missed this the first time as well. 

return (new BigInteger("FFFFFFFFFFFFFFFF", 16)).subtract((new BigInteger(Long.toHexString(sum), 16))).add(BigInteger.ONE); 

这看起来很丑,但我尽可能地使用本机算术。

您可以使用BitInteger的“toByteArray()”方法获取用于比较的原始二进制文件。不要使用longValue(),因为它破坏了第一位。

+0

谢谢,我发现最后一行也令人困惑,这就是我问这个问题的原因。试试这个代码。 –

+0

也许我只是错过了一些东西,但:100000000-10 + 1!= 10 –

+0

@ 32bitkid你的评论只是证明你不知道计算机如何算术,你甚至不会打扰谷歌之前,你做出不负责任的评论。 Tomislav Markovski:确保您以二进制比较结果,例如通过转换为字节,以便第一位不被视为Java中的符号位。 –

1

ulong在Java中没有等价物。但是,您可以使用BigInteger解决此问题。

private static BigInteger Checksum(short[] data) 
{ 
    BigInteger sum = BigInteger.ZERO; 
    for (short s : data) 
     sum = sum.add(BigInteger.valueOf((long)s)); 

    return new BigInteger("18446744073709551615", 10).subtract(sum).add(BigInteger.ONE); 
} 

而且,由于字节在Java中签,你要上去short得到0-255。

编辑:如果您的签名需要使用byte[]代替short[]匹配,然后billc.cn有答案。

+1

我只是想说,简称演员并不能解决由于符号扩展而导致的符号问题。 –

+0

@ billc.cn哪一个简短?我要投射很长时间,但不要在任何地方短路(我可以看到)。 – vcsjones

+0

您将输入内容更改为short [],我相信海报将在包装中使用cast进行实施,这可能会导致问题。我认为我们最好匹配签名并处理函数中的所有问题。 :) –