0

我有这个字节数组,我想计算得到一个 2 字节的校验和。

byte[] b = {(byte) 0x80, (byte) 0x00, (byte) 0x81, (byte) 0x01, (byte) 0x80, (byte) 0x01,(byte) 0x00, (byte)  0x00, (byte) 0x00, (byte) 0x74}; 

校验和应该是(byte) 0x01,(byte) 0xf7,但是 Java 中的方法将如何实现呢?上面的这个字节数组是 SECS-1 协议的示例标头。我使用for循环对整数中的所有字节求和,但我得到的结果仅为 0x77,它与 0x01 0xf7 相去甚远。

int sum =0;
for(int b:bytes){
    sum ^= b;
}
System.out.println(sum);

我的第二个解决方案是

for (int i = 0; i < bytes.length; i++) {
    CheckSum += bytes[i];
}
System.out.println(Integer.toHexString(CheckSum));

但我得到的值是 0xffffeff7,更接近我期望的值。

4

2 回答 2

2

Java 字节是有符号的。只需使用 (b & 0xff) 得到无符号值,然后求和。

int sum =0;
for(int b:bytes){
    sum += (b & 0xff);
}
System.out.println(sum);

然后将 sum 转换为字节数组,就像这里的Java integer to byte array

于 2013-11-27T09:32:19.203 回答
0

我想我找到了一种解决方法,但是如果你们认为这不是最好的解决方案,欢迎您改进此代码。

private byte[] calculateChecksum(byte[] bytes) {
    int f = 0x00;
    int g = 0x00;
    for (int i = 0; i < bytes.length; i++) {
        int u;
        if (bytes[i] <= -128) {
            u = ((bytes[i] - bytes[i]) + 128);
        } else if (bytes[i] >= -128 && bytes[i] < 0) {
            u = (bytes[i] + 128 + 128);
        } else {
            u = (128 - (128 - bytes[i]));
        }
        f += u;
        if (f > 256) {
            g += (f - 256);
            f = (f - 256);
        }
    }
    byte[] b = {(byte) f, (byte) g};
    return b;
}
于 2013-10-30T01:40:18.393 回答