在Python中计算结构的CRC

在Python中计算结构的CRC,python,struct,crc,pack,nrpe,Python,Struct,Crc,Pack,Nrpe,我有以下结构,来自C中的NRPE守护程序代码: typedef struct packet_struct { int16_t packet_version; int16_t packet_type; uint32_t crc32_value; int16_t result_code; char buffer[1024]; } packet; 我想将此数据格式从Python发送到C守护进程。当crc32_值为0时,计算CRC,然后将其放入结构中。我的Python代码如下所示:

我有以下结构,来自C中的NRPE守护程序代码:

typedef struct packet_struct {
  int16_t packet_version;
  int16_t packet_type;
  uint32_t crc32_value;
  int16_t result_code;
  char buffer[1024];
} packet;
我想将此数据格式从Python发送到C守护进程。当
crc32_值
0
时,计算CRC,然后将其放入结构中。我的Python代码如下所示:

cmd = '_NRPE_CHECK'
pkt = struct.pack('hhIh1024s', 2, 1, 0, 0, cmd)
# pkt has length of 1034, as it should
checksum = zlib.crc32(pkt) & 0xFFFFFFFF
pkt = struct.pack('hhIh1024s', 2, 1, checksum, 0, cmd)
socket.send(....)
守护进程正在接收这些值:
version=2 type=1 crc=FE4BBC49 result=0

但它正在计算
crc=3731C3FD

计算CRC的实际C代码为:

它被称为via:

compute_crc32((char*)数据包,sizeof(数据包))

当我将这两个函数移植到Python时,得到的结果与
zlib.crc32
返回的结果相同

我的
struct.pack
调用是否正确?为什么我的CRC计算与服务器的不同?

与:

处理与平台无关的数据格式或省略隐式pad 字节,使用标准大小和对齐方式,而不是本机大小和对齐方式 对齐:有关详细信息,请参见


使用“!”作为第一个使打包结构平台独立的格式字符。它强制使用大端、标准类型大小,并且没有填充字节。然后CRC应该是一致的。

您确定两个平台使用相同的对齐方式吗?我相信是这样的,因为打包bytestring前面的两个数值是正确的。这可能是字节排序问题。服务器可能正在使用网络(=big-endian)顺序,但您的脚本使用的是本机,因为它没有在格式字符串的开头指定任何内容并覆盖该默认值——请参阅联机文档的一节。可能性:(1)端号差异(2)字节交换差异(3)填充[对齐] differences@wberry:1)和2)基本上不是一回事吗?在前面使用“>”得到了正确的结尾,但出于某种原因,我还不得不在结尾添加一个字节。该C结构的大小是1036,而不是1034;不知道为什么…@sadris:由于内存不足,它可能会将C-struct的大小填充到最接近的整个32位(4字节)本机字大小。有些编译器可以选择打开或关闭该选项。只需比较1034字节,而不是尝试将其填充到1036字节。C结构的最后两个pad字节可能未初始化,因此添加的padding将不匹配。除非你从C结构中复制它,否则这太傻了。