crc遇到的问题
背景
参数模型: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'))