8

我在android/java中写了一个校验和计算函数。功能如下

void CalculateCheckSum( byte[] bytes ){
     short CheckSum = 0, i = 0;
     for( i = 0; i < bytes.length; i++ ){
        CheckSum = (short) ((short)CheckSum + (short)bytes[i]);
     }

     Log.i("Checksum", Integer.toHexString(CheckSum));
}

用于计算校验和的输入值为 0xEF、0x01、0xEF、0x01、0x33、0x0C、0xB8、0xE5、0xFC、0x34、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF。我手动计算了校验和值,结果是 0xCE4。使用上述函数时,我得到的答案为 0xFFFFFFE4。我的计算是否有任何错误,如果是,请纠正我。

谢谢

4

6 回答 6

2

使用调试器并调试您的代码。不过,一般来说,如果你不断地添加东西,即使你使用 anint或 a long,它也一定会在某些时候溢出,所以你会得到意想不到的结果。最好使用标准校验和算法或已经可用的类之一,例如CRC32Adler31。至于您的代码,您似乎将结果视为整数,那么为什么short首先要转换为?

intJava 使用's进行所有算术计算,因此您byte的 s 被转换为int不适合字节的那些将看起来像int's: ffffffef(-17)。自然,您只需要实际的字节值,因此您需要使用(0xff & b). 所以你的循环比变成这样:

  int checkSum = 0;

  for(byte b : bytes){
    checkSum += (0xff & b);
  }
于 2012-09-11T07:31:34.817 回答
2

这里的问题是(short)演员阵容bytes[i]。它扩展了标志。您应该更改(short)bytes[i](bytes[i] & 0xff). 这会给你正确的答案。

与大多数其他答案相反,它与字节溢出无关。您也不必更改数组类型。

于 2012-09-11T07:57:26.297 回答
1

正如 aprian 上面提到的,虽然 byte 具有十六进制值所需的 8 位,但它只能存储 -128 到 127 之间的值。因此,在这种情况下,一个快速简单的解决方案是使用下一个更大的原语short

short shorts[] = {0xEF, 0x01, 0xEF, 0x01, 0x33, 0x0C, 0xB8, 0xE5, 0xFC, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

int checkSum = 0;

for( short s : shorts){
    checkSum = checkSum + s;
}

System.out.println("Checksum: " + Integer.toHexString(checkSum));

这给了我输出:

Checksum: ce4

当然,这意味着您可能必须byte array事先进行转换。

于 2012-09-11T07:45:28.763 回答
1

byte根据Java Docs

一个字节的值介于2^(-7)(2^7)-1(-128 到 127)之间。

但是您的值0xEF(十进制 239)已经达到一个字节的限制。这就是总和给出错误数字的原因。

于 2012-09-11T07:25:22.553 回答
0

最后我得到了...

更正的代码

void CalculateCheckSum( byte[] bytes ){
         short CheckSum = 0, i = 0;
         for( i = 0; i < bytes.length; i++){
              CheckSum += (short)(bytes[i] & 0xFF);
         }
         Log.i("Checksum", Integer.toHexString(CheckSum));
    }

感谢aprian和其他人

于 2012-09-11T08:01:19.897 回答
-1

如果使用以下方法转换整数,则应使用整数作为输入:

    String CalculateCheckSum( Integer[] bytes ){
        Integer CheckSum = 0, i = 0;
        for( i = 0; i < bytes.length; i++ ){
            CheckSum += bytes[i];
        }
        return Integer.toHexString(CheckSum);
    }

这将返回预期的 0xCE4 希望这解决了您的问题

于 2012-09-11T07:37:56.530 回答