Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating CRC16 in Python

I'm trying to evaluate appropriate checksum based on CRC-16 algorithm using crcmod Python module and 2.7 version of Python interpreter. The checksum parameters are:

  • CRC order: 16
  • CRC polynomial: 0x8005
  • Inital value: 0xFFFF
  • Final value: 0x0000
  • Direct: True

Code:

crc16 = crcmod.mkCrcFun(0x18005, rev=False, initCrc=0xFFFF, xorOut=0x0000)
print hex(crc16(str(int(0x5A0001))))

and for the input 0x5A0001 it prints 0x7E16 while I should get something like 0xCE0A.

I checked on http://www.lokker.net/Java/crc/CRCcalculation2.htm and the computed value is 0xACE which is correct (with respect to the order).

like image 841
Qrlet Avatar asked Feb 04 '16 15:02

Qrlet


People also ask

What is CRC16 algorithm?

The Cyclic Redundancy Check 16 is a hash function that produces a checksum that is used to detect errors in transmissions. The CRC16 calculation module is an iterative CRC calculator that can be used to cumulatively update a CRC checksum for every incoming byte.

How is CRC 16 calculated Modbus?

We now have what we need to compute CRC-16/MODBUS, which has both a non-zero Init value ( 0xffff ) and RefIn and RefOut as true. We start with the message with the bits in each byte reflected and the first 16 bits inverted. That is 7f f7 03 c0 00 80 . Divide by 0x18005 and you get the remainder 0xb393 .

What is CRC16 Ccitt?

The CRC- 16 bits code computes a 16-bit cyclical redundancy check (CRC) algorithm on an input serial data stream. The polynomial can be defined to implement CRC functions, such as the CRC-16 or CCITT algorithm. A seed value can be specified to initialize the starting data value.

What is CRC32 in Python?

crc32 computes CRC-32 on binary text data. By definition, CRC-32 refers to the 32-bit checksum of any piece of data. This method is used to compute 32-bit checksum of provided data. This algorithm is not a general hash algorithm.


2 Answers

crcmod is working fine. You are not giving it the three bytes you think you are giving it. Your str(int(0x5A0001)) is providing seven bytes, which are the ASCII characters 5898241 — the conversion of 0x5a0001 to decimal.

To feed it the bytes 0x5a 0x00 0x01, you would instead (as one approach):

print hex(crc16("5a0001".decode("hex")))

That prints 0xace.

like image 76
Mark Adler Avatar answered Oct 04 '22 09:10

Mark Adler


Here is a python implementation of CRC-16/CCITT-FALSE

def crc16(data : bytearray, offset , length):
    if data is None or offset < 0 or offset > len(data)- 1 and offset+length > len(data):
        return 0
    crc = 0xFFFF
    for i in range(0, length):
        crc ^= data[offset + i] << 8
        for j in range(0,8):
            if (crc & 0x8000) > 0:
                crc =(crc << 1) ^ 0x1021
            else:
                crc = crc << 1
    return crc & 0xFFFF
  • data : bytearray of the data you want to calculate CRC for
  • offset : from which offset you want to start calculating CRC
  • length : to which offset you want to calculate CRC
like image 34
Amin Saidani Avatar answered Oct 04 '22 09:10

Amin Saidani