我正在尝试用Python解码Novatel GPS流,并且已经对sync、header和payload的所有组件进行了排序,但是我不能复制作为消息一部分使用的CRC32。用于生成附加在消息上的CRC的算法用c编写如下:
#include <iostream>
#include <string>
using namespace std;
#define CRC32_POLYNOMIAL 0xEDB88320L
//#define CRC32_POLYNOMIAL 0x04C11DB7L
unsigned long CRC32Value(int i)
{
int j;
unsigned long ulCRC;
ulCRC = i;
for (j = 8; j > 0; j--)
{
if (ulCRC & 1)
ulCRC = (ulCRC >> 1) ^ CRC32_POLYNOMIAL;
else
ulCRC >>= 1;
}
return ulCRC;
}
unsigned long CalculateBlockCRC32(
unsigned long ulCount,
unsigned char *ucBuffer)
{
unsigned long ulTemp1;
unsigned long ulTemp2;
unsigned long ulCRC = 0;
while (ulCount-- != 0)
{
ulTemp1 = (ulCRC >> 8) & 0x00FFFFFFL;
ulTemp2 = CRC32Value(((int)ulCRC ^ *ucBuffer++ ) & 0xff );
ulCRC = ulTemp1 ^ ulTemp2;
}
return(ulCRC);
}
int main()
{
unsigned char buffer[] = {0xaa, 0x44, 0x12, 0x1c, 0x2a, 0x00, 0x02, 0x20, 0x48, 0x00, 0x00, 0x00, 0x90, 0xb4, 0x93, 0x05, 0xb0, 0xab, 0xb9, 0x12, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xbc, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1b, 0x04, 0x50, 0xb3, 0xf2, 0x8e, 0x49, 0x40, 0x16, 0xfa, 0x6b, 0xbe, 0x7c, 0x82, 0x5c, 0xc0, 0x00, 0x60, 0x76, 0x9f, 0x44, 0x9f, 0x90, 0x40, 0xa6, 0x2a, 0x82, 0xc1, 0x3d, 0x00, 0x00, 0x00, 0x12, 0x5a, 0xcb, 0x3f, 0xcd, 0x9e, 0x98, 0x3f, 0xdb, 0x66, 0x40, 0x40, 0x00, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03};
unsigned long crc = CalculateBlockCRC32(sizeof(buffer), buffer);
cout << hex << crc << endl;
}
结果是0x42、0xdc、0x4c、0x48—这与手册中给出的示例相匹配,因此这是一个不错的开始。在
虽然我可能会在我正在编写的代码中使用这个算法,但我更希望尽可能使用Python,因此在这一点上,我觉得我有两个选择。我可以自己将其翻译成Python,也可以希望有一个内置的Python函数或模块能够为我实现这一点,这正是我一直在寻找的。到目前为止,我发现了三个功能/模块:
其中前两个给出了同样的错误结果,我无法告诉任何可能会对其产生积极影响的设置或指定参数的方法。在
另一方面,crcmod有过多的设置和预定义的功能,我认为应该能够做我正在寻找的。创建CRC函数的格式如下:
^{pr2}$我发现的一个关键问题是有预定义的CRC函数,CRC32版本与binascii和zlib的结果相匹配:
Name Polynomial Reversed? Init-value XOR-out Check
crc-32 0x104C11DB7 True 0x00000000 0xFFFFFFFF 0xCBF43926
因此,至少这有助于我理解zlib和binascii变体从所用多项式的来源。在
因此,我确信我应该能够使用这个函数生成与C算法相同的结果,但是由于不精通C,我不确定我是如何做到这一点的。在C算法中使用的多项式是多项式的反向表示,所以这意味着上面的设置应该有效,但是它们不会按照C代码生成上面的答案。在
我在寻找什么来确定这些设置?是否有一个模块/函数可以完成这一任务,但我还没有看到,或者这不起作用,我应该自己开始将C语言翻译成Python?在
对于
crcmod
,你需要在多项式前面加上1
,因为第33位必须是1,否则你会得到一个例外,说次数必须是8、16、24或32。这似乎产生了您的预期输出:下面的示例应该可以在Python 2和Python 3上正常工作:
^{pr2}$印刷品
^{3}$它是八位元
0x42, 0xdc, 0x4c, 0x48
的小端有序值。在相关问题 更多 >
编程相关推荐