resti
resti

Reputation: 45

Getting the two bytes by adding the 16 bit unsigned of the byte array as checksum

I have this array of bytes that I want to calculate to get a 2 byte checksum.

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

The checksum should be (byte) 0x01,(byte) 0xf7, but how will be the method in Java to accomplish this? This array of bytes above is the example header of SECS-1 protocol. I use the for loop to sum all the bytes in integer, but I'm getting the result of 0x77 only which is far from 0x01 0xf7.

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

my second solution was

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

but I'm getting the value 0xfffffef7, much closer to the value that I expect.

Upvotes: 0

Views: 2971

Answers (2)

FkYkko
FkYkko

Reputation: 1075

Java bytes are signed. Just get the unsigned value by using (b & 0xff) and then sum up.

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

Then convert sum to byte array like in here Java integer to byte array

Upvotes: 2

resti
resti

Reputation: 45

i think i found a workaround, but if you guys think this is not the best solution you are welcome to improved this code.

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;
}

Upvotes: 0

Related Questions