I'm trying to create the algoritm to produce the actual checksum byte (D0) in a vehicle 11-bit CAN bus message, where all values are known by scanning the current bus (which I'm trying to replicate with other values, but I cant find the mathematical relation between data and checksum byte).

here are the sample data (in hex):
D0 D1 D2 D3 D4 D5 D6 D7
9F 70 FC 70 FC 0D 0F 00
A9 7A FC 70 FC 0D 0F 00
AA 7B FC 70 FC 0D 0F 00
AB 7C FC 70 FC 0D 0F 00
AB 7C FC 70 FC 0D 0F 00
0D 7D FC 70 FC 0D 0F 60
0E 7E FC 70 FC 0D 0F 60
09 79 FC 70 FC 0D 0F 60
0A 7A FC 70 FC 0D 0F 60
0B 7B FC 70 FC 0D 0F 60

Some more data with the same checksum(0xFF) at D0:
D0 D1 D2 D3 D4 D5 D6 D7
FF 70 FC 70 FC 0D 0F 60
FF 74 F9 70 F9 0D 0F 62
FF 17 01 20 01 0D 0F 02
FF AE 0D 70 0D 0D 0F 02
FF 13 13 0 13 0D 0F 02
FF B8 10 60 10 0D 0F 02
FF 56 11 C0 11 0D 0F 02
FF 0D 2D D0 2E 0D 0F 02

Some more with another known and same checksum (0x16):
D0 D1 D2 D3 D4 D5 D6 D7
16 7E FF 70 FF 0D 0F 62
16 7E FF 70 FF 0D 0F 62
16 F0 03 50 0B 0D 0F 02
16 78 13 B0 13 0D 0F 02
16 F9 2E 00 27 0D 0F 02
16 EE FF 60 FF 0D 0F 02

D0 = checksum
D1,D2,D3,D4 = torque values (critical)
D5 = Engine coolant temp
D6,D7 = No important engine data


  • 2
    Having so many messages with the same checksum strikes me as odd. I tried typical bytewise addition and it gets you close, but it's always off by a bit. For example for the 0x16 messages I can calculate 0x6A and 0x6C. If they were the same you could just assume a hidden constant and fix it but it's odd. Xor seems to perform worse. I don't think it's a complex algorithm but I can't figure it out. – Johann Aydinbas Sep 16 '18 at 18:24
  • It's obviously not a checksum if the following bytes are different for the same initial value. It looks more like a control/message/id byte to me. – Twifty Sep 16 '18 at 18:28
  • I think it is: ((D1+D2+D3+D4+D5+D6+D7)-85)&0xFF, I will verify it today, but sometimes it does not match, like +/-1 what it should be, very strange. – N.C Sep 17 '18 at 5:00
  • ((D1+D2+D3+D4+D5+D6+D7)-85)&0xFF, getting close, but it is not the correct method. – N.C Sep 17 '18 at 9:22

OP was getting close with D0=((D1+D2+D3+D4+D5+D6+D7)-85)&0xFF. That's not the correct method (sometimes it's off by 1), but consider the values of (D1+D2+D3+D4+D5+D6+D7)-D0: for the given data, it has the values ['-0xa8', '0x57', '0x156', '0x255', '0x354'].

What's the common property? Yes, they're all divisible by 0xFF when subtracted by 0x57.

Therefore, the checksum byte is the sum of all bytes, subtract 0x57, modulo 0xFF, then if the result is 0 then replace it with 0xFF. (alternatively this can be written as (sum - 0x58) % 0xFF + 1)

It is impossible for the checksum byte to be 0.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.