我需要帮助将此代码从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#中的(long)GetChecksum(缓冲区)相同的数字,与java中的getChecksum(缓冲区)相同。 我是java的新手,这就是我问这个的原因。
Edit2:这是最终的解决方案。许多有用的评论。谢谢你们。
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();
}
Edit2:太糟糕了,这个问题被削弱了。它有很多有用的评论。
答案 0 :(得分:1)
由于Java不会在算术溢出时抛出错误,因此您应该能够执行以下操作:
long sum = 0;
for (byte b : data)
sum += (long) b;
return sum;
基于您希望与C#中的结果完全相同(二进制而不是值)的假设,简化了返回。 ulong.MaxValue
是64位的1,在签名长度中为-1,取消“+1”。
Edit2:由于有符号减法的行为不均匀,因此无法简单地模拟无符号运算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(),因为它会破坏第一位。
答案 1 :(得分: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会有答案。