这两段代码之间有什么区别

时间:2014-06-29 20:58:54

标签: python struct

大家好我有两段代码,令我困惑的是,虽然它们应该是等价的,但是在运行这两段代码时我没有收到相同的结果,它们之间有什么区别?

这是第一个和工作部分:

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload

和第二个非工作部分:

#     packet = struct.pack(">B", relayCmd)
#     packet += struct.pack("H", 0)
#     packet += struct.pack("H", streamId)
#     packet += struct.pack("L", 0)
#     packet += struct.pack("H", len(payload))
#     packet += payload

3 个答案:

答案 0 :(得分:2)

在第一个版本中,您通过“>”指定Big Endian的格式然后所有格式参数都以这种方式编码。在第二个示例中,仅在第一行中指定Big Endian,然后使用系统的 native 编码对所有其他参数进行编码(默认使用“@”)。

答案 1 :(得分:1)

来自struct文档:

  

注意:默认情况下,打包给定C结构的结果包括填充字节,以便维护所涉及的C类型的正确对齐;类似地,在拆包时考虑对齐。选择此行为,以便打包结构的字节与相应C结构的内存中的布局完全对应。要处理与平台无关的数据格式或省略隐式填充字节,请使用standard大小和对齐而不是native大小和对齐:有关详细信息,请参阅字节顺序,大小和对齐。

如果未指定其他4行的对齐方式,则使用默认的@对齐(使用native对齐方式)。您只对第一个>代码点使用了relayCmd标准对齐方式。

因此,产生的尺寸是不同的:

>>> import struct
>>> struct.calcsize('>BHHLH')
11
>>> struct.calcsize('>B')
1
>>> struct.calcsize('H')
2
>>> struct.calcsize('L')
8
>>> 1 + 3 * 2 + 8
15

不同之处在于填充L;如果您对所有 >次调用使用pack()大端标记,则只需四个字节:

>>> struct.calcsize('>L')
4

这样可行:

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

答案 2 :(得分:1)

你必须在每个字母前加上>,所以一切都是大端的。

#!/usr/bin/env python2

import struct

relayCmd = 170
streamId = 10000
payload = "A"

packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))

packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload

print(''.join("{:02x} ".format(ord(i)) for i in packet))