I'm trying to calculate a checksum, and I have to admit my binary manipulation knowlege is failing me.
If anyone could help with the below (and improve the title of this question) I'd be most grateful.
(I've tried quite a lot of things, but I think I'm just not going about it correctly)
A previous question I asked is here, but the technique is different, I think - How to build byte array frame and calculate checksum
To avoid the checksum coinciding with any of the control bytes (0x02 and 0x03), the checksum is divided into two bytes. In the first byte the four least significant bits are introduced, and the four most significant ones in the second.
Example:
Checksum calculation of the following command:
STX 0x02
Filler1 0x30
Filler2 0x30
Address 0x81
Type 0x56 “V”
Tray 0x8B
Belt 0x82
Checksum1 0xF6
Checksum2 0x4F
ETX 0x03
Add the values of every byte previous to the checksum. The result is obtained as an unsigned char
.
Checksum = 0x02+0x30+0x30+0x81+0x56+0x8B+0x82 = 0x46
Set the four most significant bits to “1” using OR operator, forming Checksum1
, where the four least significant bits of Checksum
are stored.
Checksum1 = Checksum | 0xF0 = 0x46 | 0xF0 = 0xF6
Change the four least significant bits to “1” using OR operator, forming Checksum1
, where the four most significant bits of Checksum are stored.
Checksum2 = Checksum | 0x0F = 0x46 | 0x0F = 0x4F
def print_bytes(bytes):
print("\n" + " ".join("\\x%02X" % v for v in bytes))
frame = bytearray([0x02,0x30,0x30,0x81,0x56,0x8B,0x82])
print_bytes(sum(frame).to_bytes(2, "little"))
\x46 \x02
The result is obtained as an unsigned char.
This means that you must only use the 8 least significant bits to calculate.
>>> (0x02 + 0x30 + 0x30 + 0x81 + 0x56 + 0x8b + 0x82)
582
>>> (0x02 + 0x30 + 0x30 + 0x81 + 0x56 + 0x8b + 0x82) & 0xff
70
And then within those 8 bits you need to set the 4 most and least significant bits.
>>> 70 | 0xf0
246
>>> 70 | 0x0f
79
This then results in 0xf6 and 0x4f as shown in the checksum bytes.