计算crc校验遇到的问题

crc遇到的问题

  • 背景
  • 使用方法
    • 方法一 不好用 计算crc16modbus好用 剩下是默认的modbus/arc
    • 方法2 网上找的教程 不知道是不是设置不对,结果设置的参数没起作用
  • 方法3 得到的结果和网上一样 就是有两个小坑
  • crc验证网址 [链接](https://crccalc.com/)

背景

参数模型:CRC-16/USB
宽度:16
多项式:8005
初始值:FFFF
结果异或值:FFFF
输入反转:true
输出反转:true

在使用crc校验的时候,上面的需求,网上查找资料 计算crc16 得到的结果和网上给出的结果不一
样,

使用方法

方法一 不好用 计算crc16modbus好用 剩下是默认的modbus/arc

计算crc16


class CRC16(object):
    crc16_tab = []

    # The CRC's are computed using polynomials. Here is the most used
    # coefficient for CRC16
    crc16_constant = 0xA001  # 40961

    def __init__(self, modbus_flag=False):
        # initialize the precalculated tables
        if not len(self.crc16_tab):
            self.init_crc16()
        self.mdflag = bool(modbus_flag)

    def calculate(self, input_data=None):
        try:
            is_string = isinstance(input_data, str)
            is_bytes = isinstance(input_data, bytes)

            if not is_string and not is_bytes:
                raise Exception("Please provide a string or a byte sequence "
                                "as argument for calculation.")

            crcValue = 0x0000 if not self.mdflag else 0xffff

            for c in input_data:
                d = ord(c) if is_string else c
                tmp = crcValue ^ d
                rotated = c_ushort(crcValue >> 8).value
                crcValue = rotated ^ int(self.crc16_tab[(tmp & 0x00ff)], 0)

            return crcValue
        except Exception as e:
            print("EXCEPTION(calculate): {}".format(e))

    def init_crc16(self):
        '''The algorithm uses tables with precalculated values'''
        for i in range(0, 256):
            crc = c_ushort(i).value
            for j in range(0, 8):
                if (crc & 0x0001):
                    crc = c_ushort(crc >> 1).value ^ self.crc16_constant
                else:
                    crc = c_ushort(crc >> 1).value
            self.crc16_tab.append(hex(crc))

方法2 网上找的教程 不知道是不是设置不对,结果设置的参数没起作用


import crcmod.predefined

# 创建CRC对象
crc_func = crcmod.predefined.mkPredefinedCrcFun('crc-16')

# 设置CRC多项式为8005
crc_func.generator = 0x8005

# 设置初始值为FFFF 
crc_func.initCrc = 0xffff

# 设置结果异或值为FFFF
crc_func.finalXor = 0xFFFF

# 设置输入反转和输出反转为True
crc_func.reflectIn = True
crc_func.reflectOut = True

# 计算CRC值
input_string = r"2021-01-29 12:33:22"
crc_value = crc_func(bytes(input_string, 'utf-8'))

print(hex(crc_value))  # 输出CRC值(十六进制)

方法3 得到的结果和网上一样 就是有两个小坑

crcmod.mkCrcFun的参数

  • 第一个参数 是多项式 8005 是十六进制 但是如果直接输入8005 会报错 调试ValueError: The degree of the polynomial must be 8, 16, 24, 32 or 64 我的理解 是16进制就是在2**16位置写个1,就是0x10000+0x8005 写18005 这是一个坑
  • initCrc 是初始crc值 但是 这是0xffff的话 计算结果 arc的 设置0000 得到的结果反倒是与网上crcinit值为0xffff的值一样
  • xorOut 输出异或0xffff
  • rev 输出输入反转 是不是反转
import crcmod
input_string = "1234"
crc_func = crcmod.mkCrcFun(0x18005, initCrc=0x0000, xorOut=0xffff,rev=1)
res = crc_func(bytes(input_string, 'utf-8'))

crc验证网址 链接

你可能感兴趣的:(python,开发语言)