【问题标题】:python struct unpack length errorpython struct解包长度错误
【发布时间】:2017-12-11 09:45:28
【问题描述】:

我有一个长度为 41 的字节对象。我尝试用以下方法解压它:

struct.unpack('2B2B32sBi',data)

但我收到一个错误:

struct.error: unpack 需要一个长度为 44 的字节对象

查看python文档后,我认为2B2B32sBi的长度应该是2*1+2*1+32*1+1+4=41。为什么我错了?

【问题讨论】:

  • unpack 必须有一个 exact 格式正确长度的缓冲区,超出是一个错误,因此您必须截断/切片以解压缩可变长度等早期信息,然后创建包含它们的新格式,例如: format2 = format1 + str(len) + 's'

标签: python python-3.x


【解决方案1】:

您刚刚遇到 padding,因为您首先获得字节数据,然后是整数(具有更强的对齐约束)

来自documentation

填充只会在连续的结构成员之间自动添加。编码结构的开头或结尾不添加任何填充。

所以你必须指定一个字节序来禁用填充:

struct.unpack('<2B2B32sBi',data)

为完整性而编辑,在阅读了 Galen 的出色回答后:如果您不想强制字节顺序,只需指定 = 会更好。

【讨论】:

    【解决方案2】:

    请参阅documentation 中有关对齐的部分:

    默认情况下,C 类型以机器的本机格式和字节顺序表示,并在必要时通过跳过填充字节来正确对齐(根据 C 编译器使用的规则)。

    本机大小和对齐方式是使用 C 编译器的 sizeof 表达式确定的。这总是与本机字节顺序相结合。

    注意 '@' 和 '=' 之间的区别:两者都使用原生字节顺序,但后者的大小和对齐方式是标准化的。

    为了说明这一点:

    >>> import struct
    >>> struct.calcsize("2B2B32sBi")
    44
    >>> struct.calcsize("@2B2B32sBi")
    44
    >>> struct.calcsize("=2B2B32sBi")
    41
    

    【讨论】:

      【解决方案3】:

      您可能想再次阅读struct documentation 中的第一个注释。 默认是 C 对齐的数据边界,因此一些填充字节是造成差异的原因。所以添加适当的字节顺序应该可以解决问题。

      【讨论】:

        猜你喜欢
        • 2011-04-14
        • 1970-01-01
        • 1970-01-01
        • 2019-03-31
        • 2016-05-07
        • 1970-01-01
        • 2020-04-08
        • 2020-11-03
        • 1970-01-01
        相关资源
        最近更新 更多