I wrote a checksum calculation function in android/java. the function as follows
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));
}
input values for calculation of checksum are 0xEF, 0x01, 0xEF, 0x01, 0x33, 0x0C, 0xB8, 0xE5, 0xFC, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF. I manually calculated the checksum value and result is 0xCE4. When using the above function i get answer as 0xFFFFFFE4. Is any error in my calculation, if yes then please correct me.
thanks
Use a debugger and debug your code. Generally though, if you keep adding stuff up, even if you use an int
or a long
, it is bound to overflow at some point, so you will get unexpected results. Best to use a standard checksum algorithm or one of the already available classes such as CRC32
or Adler31
. As for your code, you seem to be treating the result as an integer, so why cast to short
in the first place?
Java does all arithmetic calculations using int
's, so your byte
s get converted to int
and the ones that don't fit into a byte will look like this as int
's: ffffffef
(-17). Naturally you only need the actual byte value, so you need to zero out everything else using (0xff & b)
. So your loop than becomes something like this:
int checkSum = 0;
for(byte b : bytes){
checkSum += (0xff & b);
}
The problem here is the (short)
cast of bytes[i]
. It extends the sign. You should change (short)bytes[i]
to (bytes[i] & 0xff)
. This will give you the correct answer.
It has nothing to do with byte overflow, contrary to most of the other answers. You don't have to change the array type either.
byte
according to Java Docs :
The value of a byte is ranged between
2^(-7)
and(2^7)-1
(-128 to 127).
But your value 0xEF
(in decimal 239) has already reached the limit of a byte. That's what cause the sum give the wrong numbers.
As mentioned above by aprian, while byte has the necessary 8 bits for your hex values, it can only store values between -128 and 127. So a quick and easy solution would be to use the next bigger primitive, in this case 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));
That gives me the output:
Checksum: ce4
Of course this means you might have to convert your byte array
beforehand.
finally i got...
corrected code
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));
}
thanks to aprian and others
You should use integers as input if you convert them with:
String CalculateCheckSum( Integer[] bytes ){
Integer CheckSum = 0, i = 0;
for( i = 0; i < bytes.length; i++ ){
CheckSum += bytes[i];
}
return Integer.toHexString(CheckSum);
}
this will return the expected 0xCE4 hope this fixed your problem
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.