Python计算CRC16

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python计算CRC16相关的知识,希望对你有一定的参考价值。

参考技术A 用于计算 modbus 通信协议的 CRC16 校验值。
举例: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 得到校验值为 0xB0CF (或 0xCFB0 )
计算方法,分两种,直接计算和查表计算。

Python CRC8 计算

【中文标题】Python CRC8 计算【英文标题】:Python CRC8 calculation 【发布时间】:2019-02-22 18:36:49 【问题描述】:

我有一些字节想在 python 中计算 CRC8。

我没有这方面的经验,但我知道,根据我设备的技术规格,这个计算必须使用 0x07 多项式和 0x00 初始化。

让我们来看一个用例。我收到了这个字节列表,我知道最后一个是 CRC:

0x00 0x11 0x23 0x32 0x1C 0xAC 0x23 0x3F 0x25 0x47 0x3D 0xB7 0xE2 0xC5 0x6D 0xB5 0xDF 0xFB 0x48 0xD2 0xB0 0x60 0xD0 0xF5 0xA7 0x10 0x96 0xE0 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xC5 0x8A

现在,我如何计算我方的 CRC 以检查它是否对应于 0x8A?

我进行了一些研究并尝试了不同的 python 模块,如 crcmod、crc8 和 libscrc,但我无法让它们工作:有时我在控制台上出现 MemoryError 错误!

我也尝试过使用以下代码,但它似乎没有返回我认为正确的 CRC (0x8a):

import crc8
hash = crc8.crc8()
hash.update("0x001123321CAC233F25473DB7E2C56DB5DFFB48D2B060D0F5A71096E00000000000000000C58A".encode('utf-8'))
print( hash.hexdigest() )

我做错了什么?

有没有经验的人可以帮助我?也许发布一个我可以用来进行计算的sn-p代码?

但是,我们将不胜感激! 非常感谢您的支持...

【问题讨论】:

如果您对包括 CRC 字节在内的整个消息计算 CRC8,则计算出的 CRC8 应该为零。如果您对消息的 CRC8 字节以外的所有字节计算 CRC8,您应该得到 CRC8 = 0x8a。 谢谢@rcgldr!我认为我的问题更进一步:不知道如何解决这些内存错误。你有一些我可以使用的python代码示例吗? 我对 Python 不是很熟悉,更不用说它的库了。我可以用 C 创建一些东西,但应该已经有用 C 实现的 CRC8 示例。 crc8.crc8() 采用 bytes 对象。你给它一串十六进制数字。在 Python 3 中,您可以使用 int('0x1234', 16).to_bytes(2, 'big') 之类的方式将此字符串转换为字节(确保正确设置长度)。最有可能的是,任何给你数据的东西已经是bytes,你实际上不需要转换。如果你了解b'00'b'\x00' 之间的区别,你就会明白你的代码出了什么问题。 【参考方案1】:
import crc8

hash = crc8.crc8()
hash.update("001123321CAC233F25473DB7E2C56DB5DFFB48D2B060D0F5A71096E00000000000000000C5".decode("hex"))
print( hash.hexdigest() )

输出:

8a

【讨论】:

【参考方案2】:

0x8a对应一个标准的CRC-8:

width=8  poly=0x07  init=0x00  refin=false  refout=false  xorout=0x00  check=0xf4  residue=0x00  name="CRC-8"

您链接到的 Python crc8 将完全按照您的意愿行事。

例如(在 Python 3 中):

hash.update(b'\x00\x11\x23\x32\x1C\xAC\x23\x3F\x25\x47\x3D\xB7\xE2\xC5\x6D\xB5\xDF\xFB\x48\xD2\xB0\x60\xD0\xF5\xA7\x10\x96\xE0\x00\x00\x00\x00\x00\x00\x00\x00\xC5')
print(hash.hexdigest())

给予:

8a

如果您在数据中包含8a,则结果为零。

【讨论】:

谢谢马克,所以我想知道为什么我的代码似乎没有返回正确的(至少我认为是)0x8A CRC 代码。代码如下: import crc8 hash = crc8.crc8() hash.update("0x001123321CAC233F25473DB7E2C56DB5DFFB48D2B060D0F5A71096E00000000000000000C58A".encode('utf-8')) print( hash.hexdigest() )我做错了吗? 将该代码放入您的问题中。您似乎对字节列表的实际含义有一个非常基本的误解。 谢谢你,马克,我现在已经把代码放在我的问题中了。是的,我知道,我没有在 python 中处理字节的经验。但是,字节列表是什么意思?你的意思是我必须使用bytes 对象吗? 是什么意思?你是那个说“我已经收到这个字节列表”的人。你是怎么收到的? CRC 需要给出实际的二进制字节。不是文本字符串中字节的十六进制表示。

以上是关于Python计算CRC16的主要内容,如果未能解决你的问题,请参考以下文章

CRC-CCITT 16 位 Python 手动计算

CRC16校验码如何计算

CRC-16/MODBUS计算详细步骤

问一下计算机大神。crc16与crc32有啥区别

谁会crc16-ccitt的计算方法,用winform做的,谢谢啦。。。

计算 CRC16 (Modbus) 值的函数