Fol*_*lau 2 python crc32 python-2.x
我正在尝试在 Python 中解码 Novatel GPS 流,并且我已对同步、标头和有效负载的所有组件进行了排序,但我无法复制用作消息一部分的 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;
}
Run Code Online (Sandbox Code Playgroud)
结果是 0x42, 0xdc, 0x4c, 0x48 - 这与手册中给出的例子相匹配,所以这是一个很好的开始。
虽然我可能会在我正在编写的代码中使用这个算法,但我更愿意尽可能留在 Python 中,所以在这一点上我觉得我有两个选择。我可以自己将它翻译成 Python,或者希望有一个内置的 Python 函数或模块能够为我做这件事,这就是我一直在寻找的。到目前为止,我发现了三个功能/模块:
其中前两个给出了相同的错误结果,我无法说出任何可能对其产生积极影响的更改设置或指定参数的方法。
另一方面,crcmod 有大量的设置和预定义的功能,我认为它们应该能够满足我的需求。创建CRC函数的格式如下:
crcmod.mkCrcFun(poly[, initCrc, rev, xorOut])
Run Code Online (Sandbox Code Playgroud)
我发现的最重要的事情是有预定义的 CRC 函数,它的 CRC32 版本与来自 binascii 和 zlib 的结果相匹配:
Name Polynomial Reversed? Init-value XOR-out Check
crc-32 0x104C11DB7 True 0x00000000 0xFFFFFFFF 0xCBF43926
Run Code Online (Sandbox Code Playgroud)
所以至少这可以帮助我了解 zlib 和 binascii 变体在使用的多项式方面的来源。
我确信因此我应该能够使用此函数生成与 C 算法相同的结果,但不精通 C 我不确定我是如何做到这一点的。C 算法中使用的多项式是多项式的反向表示,因此这意味着上面的设置应该有效,但它们不会根据 C 代码生成上面的答案。
我在寻找什么来确定这些设置,是否有一个模块/函数可以做到这一点我没有见过,或者这不会起作用,而我应该自己开始将该 C 翻译成 Python?
对于crcmod,您需要1在多项式的前面添加,因为第 33 位需要是1,否则您会收到一个异常,说明度数必须是 8、16、24 或 32。这似乎产生了您预期的输出:
import crcmod
crc = crcmod.mkCrcFun(0x104C11DB7, 0, True, 0)
Run Code Online (Sandbox Code Playgroud)
然后这个下面的例子应该在 Python 2 和 3 上正常工作:
value = bytes(bytearray(
[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]))
print(hex(crc(value))))
Run Code Online (Sandbox Code Playgroud)
印刷
0x484cdc42
Run Code Online (Sandbox Code Playgroud)
这是 octets 的 little-endian 有序值0x42, 0xdc, 0x4c, 0x48。
| 归档时间: |
|
| 查看次数: |
2275 次 |
| 最近记录: |