Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

8-bit checksum is off by one

Need help figuring out an 8-bit checksum. The data is 132byte vectors. I thought I had the checksum figured out as I am able to transfer ~30kb of data before I hit the last segment of data shown blow which the checksum fails on. Its off by one.

d1 = [0x00, 0x00, 0xff, 0x00, 0x00, 0x44, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xff, 0x00, 0x10, 0x11, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xff, 0x00, 0x10, 0x12, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xff, 0x00, 0x10, 0x13, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xff, 0x00, 0x10, 0x14, 0xff, 0x00, 0x10, 0x18, 0xff, 0x00, 0x10, 0x1c, 0xff, 0x00, 0x10, 0x20, 0xff, 0x00, 0x10, 0x24, 0xff, 0x00, 0x10, 0x28, 0xff, 0x00, 0x10, 0x2c, 0xff, 0x00, 0x10, 0x30, 0xff, 0x00, 0x10, 0x34, 0xff, 0x00, 0x10, 0x38, 0xff, 0x00, 0x10, 0x3c, 0xff, 0x00, 0x10, 0x40, 0xff, 0x00, 0x10, 0x44, 0xff, 0x00, 0x10, 0x48, 0xff, 0x00, 0x10, 0x4c, 0xff, 0x00, 0x10, 0x50, 0x00, 0x08]
d2 = [0x00, 0x08, 0xff, 0x00, 0x10, 0x54, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x40, 0x3d, 0x00, 0x00, 0x40, 0x0d, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x40, 0x19, 0x00, 0x00, 0x40, 0x49, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x40, 0x25, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x42, 0x8d, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x40, 0x31, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x00, 0x44, 0xf4, 0x00, 0x10]
d3 = [0x00, 0xd0, 0xb3, 0x01, 0x00, 0x02, 0x62, 0x01, 0xf0, 0x00, 0x61, 0x00, 0xf0, 0x00, 0xe0, 0x80, 0x03, 0x74, 0x21, 0x20, 0xf0, 0x00, 0x91, 0xf0, 0x55, 0x55, 0xe0, 0x80, 0x03, 0x96, 0x21, 0x20, 0x20, 0xb0, 0xb0, 0x01, 0x00, 0x02, 0x62, 0x01, 0xf0, 0x00, 0xe1, 0x00, 0xaa, 0xaa, 0xe0, 0x80, 0x03, 0x96, 0x21, 0x20, 0x23, 0xb0, 0xb3, 0x01, 0x00, 0x02, 0x62, 0x01, 0xf0, 0x00, 0x61, 0x00, 0xf0, 0x00, 0xe0, 0x80, 0x03, 0x96, 0x21, 0x20, 0xf0, 0x00, 0x91, 0xf0, 0x55, 0x55, 0xe0, 0x80, 0x03, 0x94, 0x21, 0x20, 0x20, 0xb0, 0xb0, 0x01, 0x00, 0x02, 0x62, 0x01, 0xf0, 0x00, 0xe1, 0x00, 0xaa, 0xaa, 0xe0, 0x80, 0x03, 0x94, 0x21, 0x20, 0x23, 0xb0, 0xb3, 0x01, 0x00, 0x02, 0x62, 0x01, 0xf0, 0x00, 0xe0, 0x80, 0x03, 0x94, 0x61, 0x00, 0x21, 0x20, 0xb0, 0x82, 0x00, 0x04, 0xe0, 0x00, 0xc8, 0x00, 0x00, 0xd8]
d4 = [0x00, 0xd8, 0xa0, 0x2c, 0xff, 0x96, 0x7e, 0x21, 0xf0, 0x00, 0x2e, 0xef, 0x1f, 0xce, 0x2e, 0x7f, 0xf0, 0x00, 0xe0, 0x80, 0x04, 0x10, 0x20, 0x90, 0x50, 0x59, 0xb0, 0xa0, 0x00, 0x05, 0xe0, 0x00, 0xc5, 0x00, 0xa0, 0x2c, 0xff, 0x96, 0x7e, 0x19, 0xf0, 0x00, 0x7f, 0x05, 0xf0, 0x00, 0xe0, 0x80, 0x04, 0x10, 0x21, 0x90, 0xf0, 0x00, 0x81, 0xc1, 0x00, 0xbf, 0x21, 0x00, 0xf0, 0x00, 0x2e, 0xef, 0x1f, 0xce, 0x2e, 0x7f, 0xf0, 0x00, 0xe0, 0x80, 0x00, 0x04, 0x20, 0x90, 0x61, 0x07, 0xb0, 0x01, 0x00, 0x04, 0xe0, 0x00, 0xc9, 0x00, 0xa0, 0x2c, 0xff, 0x96, 0x7e, 0x0c, 0xf0, 0x00, 0x2e, 0xef, 0x1f, 0xce, 0x2e, 0x7f, 0xf0, 0x00, 0xe0, 0x00, 0xcb, 0x00, 0xa0, 0x2c, 0xff, 0x96, 0x7e, 0x11, 0xf0, 0x00, 0x2e, 0xef, 0x1f, 0xce, 0x2e, 0x7f, 0xf0, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xa0, 0x2c, 0xff, 0x96, 0x00, 0xe0]
d5 = [0x03, 0x80, 0x40, 0xff, 0x20, 0x01, 0xfe, 0x00, 0x00, 0x79, 0x49, 0x01, 0xf0, 0x00, 0x80, 0x49, 0x00, 0x03, 0x7c, 0xf5, 0x2e, 0xef, 0x29, 0xef, 0x28, 0xef, 0x1f, 0xce, 0xf0, 0x00, 0x28, 0x7f, 0x29, 0x7f, 0x2e, 0x7f, 0x69, 0x00, 0x7f, 0x0b, 0xf0, 0x00, 0x98, 0xc9, 0x00, 0x02, 0xe0, 0x80, 0x61, 0xa8, 0x08, 0xa0, 0xf0, 0x00, 0xfe, 0x00, 0x00, 0x6a, 0x20, 0xc8, 0x20, 0x90, 0xb0, 0x80, 0x00, 0x03, 0x21, 0xc8, 0x20, 0x91, 0x40, 0xff, 0x20, 0x01, 0xfe, 0x00, 0x00, 0x68, 0x49, 0x01, 0xf0, 0x00, 0x80, 0x49, 0x00, 0x02, 0x7c, 0xf5, 0x2e, 0xef, 0x29, 0xef, 0x28, 0xef, 0x1f, 0xce, 0xf0, 0x00, 0x2e, 0x7f, 0x7e, 0x1b, 0x61, 0x01, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x17, 0xe0, 0x80, 0x07, 0xe2, 0x21, 0x90, 0xf0, 0x00, 0x81, 0xc1, 0x00, 0xef, 0x21, 0x00, 0x21, 0x90, 0x81, 0xe1, 0x00, 0x10, 0x03, 0x88]
d6 = [0x03, 0x90, 0x20, 0x29, 0x21, 0xb9, 0x42, 0x01, 0xf0, 0x00, 0x80, 0xc1, 0xff, 0x00, 0x50, 0x28, 0x20, 0x08, 0xa1, 0x08, 0x00, 0x01, 0x48, 0x02, 0x49, 0x02, 0x80, 0x42, 0x00, 0x80, 0x7c, 0xf8, 0x60, 0x01, 0x2e, 0xef, 0x29, 0xef, 0x28, 0xef, 0x1f, 0xce, 0x28, 0x7f, 0x18, 0x85, 0x29, 0x7f, 0x19, 0x84, 0x2e, 0x7f, 0x7e, 0xe7, 0x61, 0x01, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x02, 0x60, 0x00, 0x7f, 0x08, 0x90, 0xf0, 0x40, 0x40, 0x20, 0x29, 0x20, 0x98, 0xa1, 0x98, 0x00, 0x01, 0x64, 0x02, 0x50, 0x48, 0x00, 0xe1, 0x20, 0x29, 0xfe, 0xff, 0xf9, 0x6b, 0x60, 0x01, 0xf0, 0x00, 0x2e, 0xef, 0x29, 0xef, 0x28, 0xef, 0x1f, 0xce, 0x2e, 0x7f, 0xf0, 0x00, 0xe0, 0x80, 0x07, 0xe1, 0x20, 0x90, 0xf0, 0x00, 0x91, 0xf0, 0x00, 0x80, 0x80, 0xc0, 0x00, 0x80, 0xb0, 0x11, 0x00, 0x08, 0xe0, 0x80, 0x07, 0xe1, 0x03, 0x98]
d7 = [0x07, 0xa0, 0xa1, 0x0c, 0xc2, 0x5b, 0xa1, 0x0c, 0xc1, 0x8f, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc1, 0x5b, 0xa1, 0x0c, 0xc1, 0x5c, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc3, 0xbd, 0xa1, 0x0c, 0xc3, 0xbe, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x51, 0x38, 0xa1, 0x0c, 0xc1, 0xb7, 0xa1, 0x0c, 0xc3, 0x40, 0xe1, 0x02, 0x58, 0xe4, 0x50, 0x21, 0xf0, 0x00, 0x80, 0xc0, 0x00, 0x01, 0x50, 0x58, 0x50, 0x38, 0xa0, 0x0c, 0xc3, 0x72, 0xa0, 0x0c, 0xc4, 0x24, 0x10, 0x82, 0x00, 0xa1, 0x20, 0xc0, 0x20, 0x90, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x01, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc2, 0xe6, 0xa1, 0x0c, 0xc2, 0xe7, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x51, 0x38, 0xf0, 0x00, 0x07, 0xa8]
d8 = [0x07, 0xa8, 0xa1, 0x0c, 0xc2, 0xca, 0xa1, 0x0c, 0xc2, 0xcb, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc1, 0xb6, 0xa1, 0x0c, 0xc1, 0xb8, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc1, 0xce, 0xa1, 0x0c, 0xc1, 0xcf, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x51, 0x38, 0xa1, 0x0c, 0xc1, 0xd2, 0xa1, 0x0c, 0xc1, 0xd3, 0xe1, 0x02, 0x58, 0xec, 0x50, 0x21, 0x50, 0x21, 0x50, 0x21, 0xf0, 0x00, 0x80, 0xc0, 0x00, 0x01, 0x50, 0x58, 0x50, 0x38, 0xa0, 0x0c, 0xc3, 0x29, 0xa0, 0x0c, 0xc3, 0x2b, 0x10, 0x82, 0x00, 0xa1, 0x20, 0xc0, 0x20, 0x90, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x01, 0x51, 0x38, 0xf0, 0x00, 0xa1, 0x0c, 0xc2, 0x02, 0xa1, 0x0c, 0xc2, 0x04, 0x81, 0xc0, 0x00, 0x01, 0x51, 0x58, 0x50, 0x21, 0x07, 0xb0]

data = [d1, d2, d3, d4, d5, d6, d7, d8]
correct_checksums = [0xdc, 0xd3, 0xd0, 0xc8, 0xcd, 0xcd, 0xcc, 0xcd]

def checksum8bitHonda(data):
    return ((sum(bytearray(data)) ^ 0xFF) + 1) & 0xFF

def checksum8bit(data):
    return 0xff - (sum(data) >> 8)

checksum_functions = [checksum8bit]
answers = [[] for _ in checksum_functions]

for i,d in enumerate(data):
    print("-----------------------------")
    print(d)
    for j,f in enumerate(checksum_functions):
        c = f(d)
        answers[j].append(c==correct_checksums[i])
        print("%02x" % correct_checksums[i], "%02x" % c, c==correct_checksums[i])

print("")
for a in answers:
    print(a,all(a))

Output:

-----------------------------
[0, 0, 255, 0, 0, 68, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 255, 0, 16, 17, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 255, 0, 16, 18, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 255, 0, 16, 19, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 112, 0, 255, 0, 16, 20, 255, 0, 16, 24, 255, 0, 16, 28, 255, 0, 16, 32, 255, 0, 16, 36, 255, 0, 16, 40, 255, 0, 16, 44, 255, 0, 16, 48, 255, 0, 16, 52, 255, 0, 16, 56, 255, 0, 16, 60, 255, 0, 16, 64, 255, 0, 16, 68, 255, 0, 16, 72, 255, 0, 16, 76, 255, 0, 16, 80, 0, 8]
('dc', 'dc', True)
-----------------------------
[0, 8, 255, 0, 16, 84, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 64, 61, 0, 0, 64, 13, 0, 0, 68, 244, 0, 0, 64, 1, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 64, 25, 0, 0, 64, 73, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 64, 37, 0, 0, 68, 244, 0, 0, 66, 141, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 64, 49, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 0, 68, 244, 0, 16]
('d3', 'd3', True)
-----------------------------
[0, 208, 179, 1, 0, 2, 98, 1, 240, 0, 97, 0, 240, 0, 224, 128, 3, 116, 33, 32, 240, 0, 145, 240, 85, 85, 224, 128, 3, 150, 33, 32, 32, 176, 176, 1, 0, 2, 98, 1, 240, 0, 225, 0, 170, 170, 224, 128, 3, 150, 33, 32, 35, 176, 179, 1, 0, 2, 98, 1, 240, 0, 97, 0, 240, 0, 224, 128, 3, 150, 33, 32, 240, 0, 145, 240, 85, 85, 224, 128, 3, 148, 33, 32, 32, 176, 176, 1, 0, 2, 98, 1, 240, 0, 225, 0, 170, 170, 224, 128, 3, 148, 33, 32, 35, 176, 179, 1, 0, 2, 98, 1, 240, 0, 224, 128, 3, 148, 97, 0, 33, 32, 176, 130, 0, 4, 224, 0, 200, 0, 0, 216]
('d0', 'd0', True)
-----------------------------
[0, 216, 160, 44, 255, 150, 126, 33, 240, 0, 46, 239, 31, 206, 46, 127, 240, 0, 224, 128, 4, 16, 32, 144, 80, 89, 176, 160, 0, 5, 224, 0, 197, 0, 160, 44, 255, 150, 126, 25, 240, 0, 127, 5, 240, 0, 224, 128, 4, 16, 33, 144, 240, 0, 129, 193, 0, 191, 33, 0, 240, 0, 46, 239, 31, 206, 46, 127, 240, 0, 224, 128, 0, 4, 32, 144, 97, 7, 176, 1, 0, 4, 224, 0, 201, 0, 160, 44, 255, 150, 126, 12, 240, 0, 46, 239, 31, 206, 46, 127, 240, 0, 224, 0, 203, 0, 160, 44, 255, 150, 126, 17, 240, 0, 46, 239, 31, 206, 46, 127, 240, 0, 224, 0, 225, 0, 160, 44, 255, 150, 0, 224]
('c8', 'c8', True)
-----------------------------
[3, 128, 64, 255, 32, 1, 254, 0, 0, 121, 73, 1, 240, 0, 128, 73, 0, 3, 124, 245, 46, 239, 41, 239, 40, 239, 31, 206, 240, 0, 40, 127, 41, 127, 46, 127, 105, 0, 127, 11, 240, 0, 152, 201, 0, 2, 224, 128, 97, 168, 8, 160, 240, 0, 254, 0, 0, 106, 32, 200, 32, 144, 176, 128, 0, 3, 33, 200, 32, 145, 64, 255, 32, 1, 254, 0, 0, 104, 73, 1, 240, 0, 128, 73, 0, 2, 124, 245, 46, 239, 41, 239, 40, 239, 31, 206, 240, 0, 46, 127, 126, 27, 97, 1, 240, 0, 176, 1, 0, 23, 224, 128, 7, 226, 33, 144, 240, 0, 129, 193, 0, 239, 33, 0, 33, 144, 129, 225, 0, 16, 3, 136]
('cd', 'cd', True)
-----------------------------
[3, 144, 32, 41, 33, 185, 66, 1, 240, 0, 128, 193, 255, 0, 80, 40, 32, 8, 161, 8, 0, 1, 72, 2, 73, 2, 128, 66, 0, 128, 124, 248, 96, 1, 46, 239, 41, 239, 40, 239, 31, 206, 40, 127, 24, 133, 41, 127, 25, 132, 46, 127, 126, 231, 97, 1, 240, 0, 176, 1, 0, 2, 96, 0, 127, 8, 144, 240, 64, 64, 32, 41, 32, 152, 161, 152, 0, 1, 100, 2, 80, 72, 0, 225, 32, 41, 254, 255, 249, 107, 96, 1, 240, 0, 46, 239, 41, 239, 40, 239, 31, 206, 46, 127, 240, 0, 224, 128, 7, 225, 32, 144, 240, 0, 145, 240, 0, 128, 128, 192, 0, 128, 176, 17, 0, 8, 224, 128, 7, 225, 3, 152]
('cd', 'cd', True)
-----------------------------
[7, 160, 161, 12, 194, 91, 161, 12, 193, 143, 129, 192, 0, 1, 81, 88, 80, 33, 81, 56, 240, 0, 161, 12, 193, 91, 161, 12, 193, 92, 129, 192, 0, 1, 81, 88, 80, 33, 81, 56, 240, 0, 161, 12, 195, 189, 161, 12, 195, 190, 129, 192, 0, 1, 81, 88, 81, 56, 161, 12, 193, 183, 161, 12, 195, 64, 225, 2, 88, 228, 80, 33, 240, 0, 128, 192, 0, 1, 80, 88, 80, 56, 160, 12, 195, 114, 160, 12, 196, 36, 16, 130, 0, 161, 32, 192, 32, 144, 129, 192, 0, 1, 81, 88, 80, 1, 81, 56, 240, 0, 161, 12, 194, 230, 161, 12, 194, 231, 129, 192, 0, 1, 81, 88, 80, 33, 81, 56, 240, 0, 7, 168]
('cc', 'cc', True)
-----------------------------
[7, 168, 161, 12, 194, 202, 161, 12, 194, 203, 129, 192, 0, 1, 81, 88, 80, 33, 81, 56, 240, 0, 161, 12, 193, 182, 161, 12, 193, 184, 129, 192, 0, 1, 81, 88, 80, 33, 81, 56, 240, 0, 161, 12, 193, 206, 161, 12, 193, 207, 129, 192, 0, 1, 81, 88, 81, 56, 161, 12, 193, 210, 161, 12, 193, 211, 225, 2, 88, 236, 80, 33, 80, 33, 80, 33, 240, 0, 128, 192, 0, 1, 80, 88, 80, 56, 160, 12, 195, 41, 160, 12, 195, 43, 16, 130, 0, 161, 32, 192, 32, 144, 129, 192, 0, 1, 81, 88, 80, 1, 81, 56, 240, 0, 161, 12, 194, 2, 161, 12, 194, 4, 129, 192, 0, 1, 81, 88, 80, 33, 7, 176]
('cd', 'cc', False)

([True, True, True, True, True, True, True, False], False)
like image 746
Ryan Hope Avatar asked Jun 25 '18 16:06

Ryan Hope


2 Answers

It looks like the checksum is close to what you thought it were (the inverted high-order bits of sum(data)), but corrected with bit 7 of that sum, as follows:

  • add all the 128 bytes (max possible value 0x7f80)
  • get the high-order bits (15..8) of the sum, that is a = sum>>8.
  • if bit 7 of the sum is 1, add 1 to a: a += (sum&0xff) >> 7
  • invert the result: return a ^ 0xff

Or, simpler, using addition of a constant to account for bit 7 correction:

def cshc(data):
    s = sum(data) + 0x80
    h = s >> 8
    return h ^ 0xff

This gives correct answers for all of the samples you provided (there are only two that have bit7 of the sum equal to 1, so I can't confirm that adding 0x80 is the exact correction needed, try it out with more samples and print both the computed final checksum and the value of sum(data)&0xff to see that this is indeed the correct way to do it.

like image 171
Leo K Avatar answered Nov 09 '22 01:11

Leo K


The correct answer for the mystery checksum ended up being the function below:

def checksum8bit(data):
    return 0xff - ((sum(data))-1) >> 8)
like image 1
Ryan Hope Avatar answered Nov 09 '22 01:11

Ryan Hope