Chris Barry - 1 year ago 108
Python Question

Calculating a checksum, using the most and least significant bits differently

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

Documentation below:

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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download