CRC-CCITT Python 16-bit manual calculation

Problem

I am writing code for an embedded device. Many 16-bit CRC-CCITT computing solutions require libraries.

Given that using libraries is virtually impossible and a resource leak, a function is required.

Possible Solution

The following CRC calculation was found on the Internet. However, its implementation is incorrect.

http://bytes.com/topic/python/insights/887357-python-check-crc-frame-crc-16-ccitt

def checkCRC(message): #CRC-16-CITT poly, the CRC sheme used by ymodem protocol poly = 0x11021 #16bit operation register, initialized to zeros reg = 0xFFFF #pad the end of the message with the size of the poly message += '\x00\x00' #for each bit in the message for byte in message: mask = 0x80 while(mask > 0): #left shift by one reg<<=1 #input the next bit from the message into the right hand side of the op reg if ord(byte) & mask: reg += 1 mask>>=1 #if a one popped out the left of the reg, xor reg w/poly if reg > 0xffff: #eliminate any one that popped out the left reg &= 0xffff #xor with the poly, this is the remainder reg ^= poly return reg 

Existing Online Solution

The following link correctly calculates 16-bit CRC.

http://www.lammertbies.nl/comm/info/crc-calculation.html#intr

The result in "CRC-CCITT (XModem)" is the correct CRC.

Specification

I believe that calculating CRC-CCITT (XModem) in an existing online solution uses a polynomial from 0x1021 .

Question

If someone can write a new function or indicate the direction to solve the checkCRC function for the required specification. Note that using libraries or any import would not help.

+6
source share
5 answers

Below is the python port of the C library from http://www.lammertbies.nl/comm/info/crc-calculation.html for CRC-CCITT XMODEM

This library is interesting for real-world use cases, as it pre-computes the crc table to increase speed.

Usage (with string or list of bytes):

 crc('123456789') crcb(0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39) 

The test gives: '0x31c3'

 POLYNOMIAL = 0x1021 PRESET = 0 def _initial(c): crc = 0 c = c << 8 for j in range(8): if (crc ^ c) & 0x8000: crc = (crc << 1) ^ POLYNOMIAL else: crc = crc << 1 c = c << 1 return crc _tab = [ _initial(i) for i in range(256) ] def _update_crc(crc, c): cc = 0xff & c tmp = (crc >> 8) ^ cc crc = (crc << 8) ^ _tab[tmp & 0xff] crc = crc & 0xffff print (crc) return crc def crc(str): crc = PRESET for c in str: crc = _update_crc(crc, ord(c)) return crc def crcb(*i): crc = PRESET for c in i: crc = _update_crc(crc, c) return crc 

Your suggested checkCRC routine is a CRC-CCITT '1D0F' variant if you replace poly = 0x11021 with poly = 0x1021 at the poly = 0x1021 .

+9
source

The original checkCRC function checkCRC also execute "CRC-CCITT (XModem)".

Just install:

 poly = 0x1021 reg = 0 

Instead

 poly = 0x11021 reg = 0xFFFF 
+2
source

Here is the version of C that you can translate into Python:

 #define POLY 0x1021 /* CRC-16 XMODEM: polynomial 0x1021, init = 0, xorout = 0, no reflection */ unsigned crc16x(unsigned crc, unsigned char *buf, size_t len) { while (len--) { crc ^= *buf++ << 8; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; crc = crc & 0x8000 ? (crc << 1) ^ POLY : crc << 1; } return crc & 0xffff; } 

crc initialized to zero.

+1
source

Here is the function I'm using:

 def crc16_ccitt(crc, data): msb = crc >> 8 lsb = crc & 255 for c in data: x = ord(c) ^ msb x ^= (x >> 4) msb = (lsb ^ (x >> 3) ^ (x << 4)) & 255 lsb = (x ^ (x << 5)) & 255 return (msb << 8) + lsb 
+1
source

I developed a small python module to generate crc. Take a picture and check out the source code that can help you!

https://github.com/killercode/PythonCRC

Why you just need to use the following code

 import crc crccalc = crc.Crc() crccalc.setCRCccitt() # Let calculate the CRC CCITT of a value crccalc.data = "My Data" crccalc.compute() print crccalc.result 

Hope this helps :)

0
source

Source: https://habr.com/ru/post/1200010/


All Articles