我在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。我的计算中是否有任何错误,如果是,请纠正我。
谢谢
答案 0 :(得分:2)
使用调试器并调试代码。但一般情况下,如果你继续添加内容,即使你使用int
或long
,它也会在某个时刻溢出,所以你会得到意想不到的结果。最好使用标准校验和算法或已有的类之一,例如CRC32
或Adler31
。至于你的代码,你似乎将结果视为一个整数,那么为什么要首先转换为short
?
Java使用int
进行所有算术计算,因此byte
转换为int
,而不适合字节的那些将如下所示{ {1}}:int
( - 17)。当然,您只需要实际的字节值,因此您需要使用ffffffef
将其他所有内容清零。所以你的循环不会像这样:
(0xff & b)
答案 1 :(得分:2)
此处的问题是(short)
的{{1}}演员。它扩展了标志。您应该将bytes[i]
更改为(short)bytes[i]
。这将给你正确的答案。
与大多数其他答案相反,它与字节溢出无关。您也不必更改数组类型。
答案 2 :(得分:1)
byte
:
字节的值介于
2^(-7)
和(2^7)-1
之间(-128到127)。
但是你的值0xEF
(十进制239)已经达到了一个字节的极限。这就是总和给出错误数字的原因。
答案 3 :(得分:1)
如上所述,aprian虽然字节具有十六进制值所需的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
。
答案 4 :(得分: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和其他人
答案 5 :(得分:-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希望这解决了你的问题