8 bit binary checksums

Today I needed to calculate an 8bit XOR checksum. I was reading an equipment manual to understand the serial data communication protocol for "Bayern-Hessen". The manual explained the message protocol. The "send" message was explained as the following:

Binary Message Format. To ensure the integrity of messages transmitted over the network, all messages sent to or received from the instrument are formed into data packets consisting of a header character, a terminator character, and a block check code, as shown below. 

<STX><message><ETX><BCC>

 In the message above, and throughout this document, is the ASCII start-of-text character (ASCII code 2); is the ASCII end-of-text character (ASCII code 3); and  is the block check code, which is a one-byte value, represented by two hexadecimal characters. For example, a block check code of 0x43 would appear in a message as the characters “43.” (For non-programmers, 0x43 is the C language convention for denoting hexadecimal numbers.) The field varies and each variation will be discussed below. Note that the < and > characters merely delimit the message fields and do not appear in the messages. The block check code, from now on referred to as BCC is simply the exclusive-OR (XOR) of all of the bytes in the message, including the STX and ETX characters, formatted as two hexadecimal characters. For example, a fully formed status request message would look like this:

<STX>DA123<ETX>34

To be able to send and receive messages, I needed to be able to calculate the 8 bit XOR check sum of a message, something I had never done before. To make sure that I did it correctly, I wanted to be able to calculate the checksum for the message above. For the message STXDA123ETX, I should be able to calculate a checksum of 34. 

This is how I ended up calculating it. 



1. Translate all the characters from ASCII to binary. (Column A and columns C-J)

2. Rows 3-9: Line up all bytes in the word. 

3. Row 10: Count the number of ones in each column. 

4. Row 11: For each column, if there are an odd number of 1s, put 1 in that column. If there are an even number of 1s, or all 0s, put a 0 in a column. The resulting 8 bits is the checksum. In this example, the checksum is 0110100, which is 0x34 or 52 in decimal. You can use an online converter to convert between binary, hex, decimal and ASCII. 

In python, you can use the ^ to calculate the checksum of each number. I  first converted my message into decimal, and stored in a list. Then I iterated through the list. 

dec_mess = [2,68,65,49,50,51,3]
checksum = 0
for num in dec_mess:
    checksum ^= num
print(checksum)

52

The above is equivalent to 
checksum = 2^68^65^49^50^51^3

Hopefully someone out there will find this useful!

-LL

Comments

Popular posts from this blog

Converting the ASCII string value of a hex number to a hex number

Line Profiler