2016-06-27 129 views
1

我从MCU发送多条消息到我的计算机,我想使用32位循环冗余校验来验证消息是否正确。从我读过的内容来看,应该可以将CRC余数附加到最后一个消息并通过CRC函数运行。如果消息没有错误,则应该返回零(对吗?) 但是,我已经使用binascii库函数binascii.crc32()实现此操作,但未成功。使用binascii.crc32()验证校验和()

让我们举例说,我想从Python文档中给出的例子(我使用Python 3.5)内部检查消息。我将如何继续检查消息是否无错(当然这是在这个例子中)?

crc = binascii.crc32(b"hello") 
crc = binascii.crc32(b" world", crc) 

check_for_error() # <--- ? 

回答

1

最简单的方法就是将CRC以字节形式附加到消息中。然后,当您收到该消息时,您将计算除消息最后4个字节以外的所有CRC,并将其与附加的CRC字节进行比较。当然,它比你想要做的要复杂一些,但是你可以将这个策略应用到像MD5或SHA系列这样的加密哈希中。

但是,要做你要求的,你需要通过从0xffffffff中减去CRC32来反转CRC32,然后再将它转换为字节&并附加它。 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的速度慢很多

+0

谢谢!我会在今天晚些时候尝试一下,希望:) – ViggoTW