0
votes

I need to be able to calculate a CRC in order to communicate with a machine. I'm pretty new to calculating CRC's so I'm sorry if this exact question has already been answered as I'm not sure what I am looking for. Anyway, I need to compute a CCIT 16-bit CRC in Python. My message is a binary stream that looks like:

b'G18M1314D4417,2511165'

The message also begins with a STX and ends with a ETX character. I tried using this Python module:

import crc16
print(crc16.crc16xmodem(b'G18M1314D4417,2511165'))

Which returned:

61154

When the correct CRC was:

A855

What am I missing?

Edit: I'm using Python 3.3. I got the 'correct' CRC from a message sent from the machine. I'm not sure whether STX/ETX characters should be included as I have never worked with CRC's before.

1
What version of python are you using? What (text) encoding are you using? Where did you get the 'correct' CRC from? Should the STX/ETX characters be included in data being CRC'd? - Tom Dalton
I've clarified my question. - Raeven
FWIW, Serial comms to a piece for kit at my place requires everything but STX & ETX to be included for the checksum. - SiHa
I think you'll need to do some more checking that you really need that specific checksum algorithm, and that the correct CRC really is for that message - something doesn't add up but I'm afraid it's not possible to see where with this info. - Tom Dalton
I found that site for another questions on CCITT and it has online check for many CRC algorythms. And it agrees with you crc16 XModem is 61154 = 0xEEA2. But none of its list gives A855. Are you sure it is really a CRC, and that there are no other caracters at the beginning or at the end ? - Serge Ballesta

1 Answers

2
votes

I believe that your machine is using a parametrised CRC algorithm named CRC-16/MCRF4XX.

You can use the crcmod module which can be installed with pip. The CRC can be calculated using the predefined algorithm crc-16-mcrf4xx. STX and ETX should be included in the CRC calculation.

import crcmod
import crcmod.predfined

STX = b'\x02'
ETX = b'\x03'
data = b'G18M1314D4417,2511165'
message = STX + data + ETX

crc16 = crcmod.predefined.Crc('crc-16-mcrf4xx')
crc16.update(message)
crc = crc16.hexdigest()

>>> crc
'A855'