python - 8 位校验和差一

标签 python bit-manipulation bitwise-operators checksum

需要帮助计算 8 位校验和。数据是 132 字节的向量。我以为我已经计算出校验和,因为我能够传输 ~30kb 的数据,然后我到达最后一段显示的数据,校验和失败。差一分。

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))

输出:

-----------------------------
[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)

最佳答案

看起来校验和与您认为的接近(sum(data) 的反转高位位),但用该和的第 7 位进行了更正,如下所示:

  • 将所有 128 个字节相加(最大可能值为 0x7f80)
  • 得到和的高位(15..8),即a = sum>>8
  • 如果和的第 7 位为 1,则将 a 加 1:a += (sum&0xff) >> 7
  • 反转结果:return a ^ 0xff

或者,更简单,使用添加一个常量来解释第 7 位校正:

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

这为您提供的所有样本提供了正确答案(只有两个样本的总和的 bit7 等于 1,因此我无法确认添加 0x80 是否是所需的精确校正,请尝试更多样本并打印计算出的最终校验和和 sum(data)&0xff 的值,看看这确实是正确的方法。

关于python - 8 位校验和差一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51027966/

相关文章:

javascript - 两个 int 值之间按位或运算后的负值

c - 如何轻松地将一个字节的最后 x 位替换为另一个字节的 x 位?

满足方程的按位变换算法

按位运算中的困惑

c - 这段代码是怎么回事?

python - Django 中的一对多关系

python - 基于现有数据库表的动态 Django 模型创建

python - 在 Tensorflow 2.0 中用另一个张量索引张量的第 k 维

python - RuntimeError : Model class users. models.User 未声明显式 app_label 并且不在 INSTALLED_APPS 中的应用程序中

java - 从二进制转换中删除前导零