# Checksum calculation

Hello

I could do with some help with checksums.
I am reading some RFID tags which have 13 bytes. The first is always 02 and the last is 03. The penultimate one is supposedly the sum code.

So for example, with this set of bytes 02,53,65,48,48,49,66,48,52,55,48,53,03
53 is supposed to be the sum code of the preceding 10 bytes. But I don't know how this is calculated. There seem to be lots of different algorithms for generating checksums, and I hardly know anything about the subject.

I'd like to be able to check that the 12th byte is correct for the other 10, but how?

If the manufacturer reveals the algorithm used to generate the check byte, that is all you need to know.

If not, you need to reverse engineer the algorithm. That can be trivial (like a simple sum) or quite a challenge (some CRC variation, or proprietary), so first check all the available documentation for your gizmo, writing to the manufacturer if necessary.

Thanks. I've found a bit of documentation.

For this set of bytes 02 30 37 30 30 34 41 31 46 45 37 B5 03
B5 is supposed to be the sum code, and it's generated with this:

07 XoR 00 XoR 4A XoR 1F XoR E7 = B5

What does this mean?

07 XoR 00 XoR 4A XoR 1F XoR E7 = B5

30 37 30 30 34 41 31 46 45 37

Is ASCII for ‘0’ ‘7’ ‘0’ ‘0’ ‘4’ ‘A’ ‘1’ ‘F’ ‘E’ ‘7’

Oh! I thought it was some fancy logic operation!

``````   int  sum = 0;
printf ("   ");
for (int n = 1; n < N; n+=2)  {
sum ^= 16* val(vec [n]) + val (vec [n+1]);
printf ("    %02X", sum);
}
``````

val() translates an ascii character into a hex value (0-F).

bear in mind that checksums are often done such when when checking the checksum and including the checksum value, a correct checksum is zero.

``````02 51 67 48 48 67 69 55 53 52 67 67 66 03
33 43 30 30 43 45 37 35 34 43 43 42 03
3  C  0  0  C  E  7  5  4  C  C  B
3C    00    CE    75    4C    CB    FFFFFD00
3C    3C    F2    87    CB    00    FFFFFD00

02 53 65 48 48 49 66 48 52 55 48 53 03
35 41 30 30 31 42 30 34 37 30 35 03
5  A  0  0  1  B  0  4  7  0  5
5A    00    1B    04    70    23
5A    5A    41    45    35    16
``````

is yours missing a byte?

robertjenkins:
Oh! I thought it was some fancy logic operation!

there are different types of checksums. some are simply "+". others involve shifting and combining with pseudo random sequences. correct checksums are no guarantee that the values are correct

robertjenkins:
Thanks. I've found a bit of documentation.

For this set of bytes 02 30 37 30 30 34 41 31 46 45 37 B5 03
B5 is supposed to be the sum code, and it's generated with this:

07 XoR 00 XoR 4A XoR 1F XoR E7 = B5

What does this mean?

It means the bits of each byte are added together with no overflow. Can you do binary arithmetic?

Paul

Paul_KD7HB:
It means the bits of each byte are added together with no overflow. Can you do binary arithmetic?

Paul

gcjr:

A single binary digit add with no overflow, is just another expression of a logical exclusive or. You can also view it as addition modulo 2.

of course

Paul_KD7HB:
ICan you do binary arithmetic?

Paul

Thanks. I can do it on paper, not quite sure how to do it in code though no doubt there is a tutorial somewhere.

Reply #7 is correct, but perhaps more theoretical than beginners can grasp. They should consult:

https://www.arduino.cc/reference/en/language/structure/bitwise-operators/bitwisexor/

Exclusive or is performing a "binary inversion" which is widely used in crytography for both encryption, hashing and calculation of checksums. The rest is just numbers which may be represented in different ways.

``````0b00000000 ^ 0b00110011 = 0b00110011
0b00110011 ^ 0b00110011 = 0b00000000
``````

^ is the XOR operator in C, the reserved word "xor" may be used as well.

gcjr:
is yours missing a byte?

Thanks for the link. It looks very similar to mine, but no, I've got 13 bytes not 14.

i think the different between “+” and “^” is pretty clear.

i don’t think it’s obvious that hardware adder use exclusive OR

The hardware adder doesn’t “use” exclusive OR. The opcodes are different and the result (including the carry) is different.

1+0xFF = 0 with carry
1^0xFF = 0xFE, no carry

The confusion here is because some people are talking about bit operations and some about byte operations. The OP only really needs to be concerned about byte operations, and the correct solution has been put forward.

jremington:
The hardware adder doesn't "use" exclusive OR. The opcodes are different and the result (including the carry) is different.

how "+" is implemented in hardware

The checksum is in the end created using bit logic on bytes. The numbers: 30 37 30 30 34 41 31 46 45 37

Represents the ASCII characters: 0 7 0 0 4 A 1 F E 7

Which represents the hexadecimal values: 0x07 0x00 0x4A 0x1F 0xE7

And the checksum (0xB5) is derived with XOR:

``````uint8_t values[] = {0x07, 0x00, 0x4A, 0x1F, 0xE7};
uint8_t checksum = 0;
for (int i = 0; i < sizeof(values); i++) checksum ^= values[i];
Serial.print("Checksum = ");
Serial.println(checksum, HEX);
``````