I've iterated of lots of articles - for some reason I couldn't find any which describes what must be a simple procedure: How to combine a calculated CRC with the original message, so that calculating CRC again results in 0 (=checks out as correct)? I did find several examples with 'longhand' calculations (only 2 or 3 bit CRCs), but no example which uses a library function such as [crcmod][1]
(Python library).
Here's a simple program I wrote to check it out:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
import crcmod
def test_cycle():
test_str = b"123456789"
orig_msg = test_str
print("Original message: {:s}".format(orig_msg.hex()))
#~ crc_calc = crcmod.predefined.Crc('xmodem')
crc_calc = crcmod.Crc(
0x11021,
rev = False,
initCrc = 0x0000,
xorOut = 0x0000)
crc_calc.update(orig_msg)
print("CRC: {:04x}".format(crc_calc.crcValue))
lo = crc_calc.crcValue & 0xff
hi = crc_calc.crcValue >> 8
new_msg = test_str + bytes((hi, lo))
print("Crc appended: {:s}".format(new_msg.hex()))
crc_calc.update(new_msg)
print("CRC: {:04x}".format(crc_calc.crcValue))
def main(args):
test_cycle()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
There are some commented lines, from experiments with different byte ordering. The results from the program are:
Original message: 313233343536373839
CRC: 31c3
Crc appended: 31323334353637383931c3
CRC: 00ef
The first CRC (31C3
) seems to check out with correspond with the expected values for xmodem-CRC. I tried, in many ways, to combine the obtained CRC with the original string, but never obtain '0'. Am I missing something here?
crc_calc.update(new_msg)
adds the entire content of new_msg
to the CRC. Since crc_calc
already holds the result of 313233343536373839
, you are effectively calculating the CRC of 31323334353637383931323334353637383931c3
and this is indeed 00ef
.
To add only the two bytes to the calculation, use
crc_calc.update(bytes((hi, lo)))
Alternatively, use a new instance of crcmod.Crc()
, or reset the crcValue
of the existing instance before doing a new calculation
crc_calc.crcValue = 0
crc_calc.update(new_msg)
Both will give you a result of 0