我正在从MCU向计算机发送多条消息,我想使用32位循环冗余校验来验证消息是否正确。根据我的阅读,应该可以将CRC余数附加到最后一条消息并通过CRC函数运行。如果消息没有错误,那么它应该返回零(我是对的吗?) 但是,我使用binascii库函数binascii.crc32()实现了这一功能。
比如说,我想从Python文档中给出的示例内部检查消息(我使用的是Python 3.5)。我如何继续检查消息是否没有错误(当然这是在这个例子中)?
crc = binascii.crc32(b"hello")
crc = binascii.crc32(b" world", crc)
check_for_error() # <--- ?
答案 0 :(得分:1)
这样做的简单方法是将CRC以字节形式附加到消息中。然后,当您收到消息时,计算除消息的最后4个字节之外的所有CRC的CRC,并将其与附加的CRC字节进行比较。当然,它比你想做的更加繁琐,但是你可以将这个策略应用于MD5或SHA系列等加密哈希。
然而,要做你想要的事情,你需要通过从0xffffffff中减去它来反转CRC32,然后再将其转换为字节&amp;附加它。 CRC32实际上是一个反向CRC,它可以防止所有零字节的消息具有零CRC。在解码时,如果数据的CRC + CRC等于0xffffffff,则消息可能有效。
Python CRC32文档建议您使用
crc32(data) & 0xffffffff
而不是
crc32(data)
确保在所有Python版本和平台上获得相同的数值。
这是一个快速的Python 3演示。
import binascii
maxcrc = 0xffffffff
def inverse_crc(data):
crc = binascii.crc32(data) & maxcrc
invcrc = maxcrc - crc
return invcrc.to_bytes(4, 'little')
def check_crc(data):
return binascii.crc32(data) & maxcrc == maxcrc
#Test
data = b"Hello, world"
newdata = data + inverse_crc(data)
print(check_crc(newdata))
newdata = b'0x00' + newdata
print(check_crc(newdata))
<强>输出强>
True
False
请注意,您可能会收到误报:损坏的消息可能具有正确的CRC。如果您需要更高级别的保护,则应使用加密哈希。这仍然不是很完美,但是如此大的哈希值的假阳性几率极低。当然,计算MD5或SHA哈希比计算CRC32要慢 。