在 Python 中计算 CRC16

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35205702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 16:08:29  来源:igfitidea点击:

Calculating CRC16 in Python

pythonpython-2.7crc16

提问by Qrlet

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

我正在尝试使用crcmodPython 模块和 2.7 版本的 Python 解释器基于CRC-16算法评估适当的校验和。校验和参数是:

  • CRC order: 16
  • CRC polynomial: 0x8005
  • Inital value: 0xFFFF
  • Final value: 0x0000
  • Direct: True
  • CRC订单:16
  • CRC 多项式:0x8005
  • 初始值:0xFFFF
  • 最终值:0x0000
  • 直接:真实

Code:

代码:

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

and for the input 0x5A0001it prints 0x7E16while I should get something like 0xCE0A.

对于0x5A0001它打印的输入0x7E16,我应该得到类似0xCE0A.

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

我检查了http://www.lokker.net/Java/crc/CRCcalculation2.htm并且计算出的值0xACE是正确的(关于订单)。

采纳答案by Mark Adler

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

crcmod工作正常。你没有给它你认为给它的三个字节。您str(int(0x5A0001))提供了七个字节,它们是 ASCII 字符5898241- 转换0x5a0001为十进制。

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

要为其提供 bytes 0x5a 0x00 0x01,您将改为(作为一种方法):

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

That prints 0xace.

那打印0xace.

回答by Amin Saidani

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

这是 CRC-16/CCITT-FALSE 的 Python 实现

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
  • data : 要为其计算 CRC 的数据的字节数组
  • offset :您要从哪个偏移量开始计算 CRC
  • length : 您要计算 CRC 的偏移量

回答by user11436151

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
    print("uzunluk=", len(data))
    print(data)

    crc = 0xFFFF
    for i in range(length):
        crc ^= data[offset + i]
        for j in range(8):
            print(crc)
            if ((crc & 0x1) == 1):
                print("bb1=", crc)
                crc = int((crc / 2)) ^ 40961
                print("bb2=", crc)
            else:
                crc = int(crc / 2)
    return crc & 0xFFFF

回答by Sz'

A working single function example for CRC-16-ANSI, CRC-16-IBM based on pycrc code.

基于 pycrc 代码的 CRC-16-ANSI、CRC-16-IBM 的工作单功能示例。

It is easy to modify but input or output reflection capability is not included:

很容易修改,但不包括输入或输出反射能力:

def crc16(data: bytes):
    xor_in = 0x0000  # initial value
    xor_out = 0x0000  # final XOR value
    poly = 0x8005  # generator polinom (normal form)

    reg = xor_in
    for octet in data:
        # reflect in
        for i in range(8):
            topbit = reg & 0x8000
            if octet & (0x80 >> i):
                topbit ^= 0x8000
            reg <<= 1
            if topbit:
                reg ^= poly
        reg &= 0xFFFF
        # reflect out
    return reg ^ xor_out