【问题标题】:Decoding packed data into a structure将打包数据解码为结构
【发布时间】:2009-12-10 09:50:46
【问题描述】:

将 python 字符串解压缩到字段中的最佳方法是什么

我从一个 tcp 套接字接收到数据,它被打包如下,我相信它会在来自套接字 recv 函数的字符串中

格式如下

uint8 - 标题
uint8 - 长度
uint32 - 类型ID
uint16 -param1
uint16 -param2
uint16 -param3
uint16 -param4
char[24] - 名称字符串
uint32 - 校验和
uint8 - 页脚

(我还需要将其他不同格式的包解包到上面)

如何解压这些?

我是 python 新手,已经做了一点“C”。如果我使用“C”,我可能会使用结构,这会是使用 Python 的方式吗?

问候

X

【问题讨论】:

    标签: python string unpack


    【解决方案1】:

    struct 模块旨在根据格式字符串将异构数据解包为元组。一次解压缩整个结构比尝试一次提取一个字段更有意义。这是一个例子:

    fields = struct.unpack('!BBI4H20sIB', data)
    

    然后你可以访问给定的字段,例如第一个字段:

    fields[0]
    

    您也可以使用元组来初始化 NamedTuple;以documentation for struct 为例。 NamedTuples 仅在 Python 2.6+ 中可用,但它们的行为更像 Python 结构,因为您可以将元素作为属性访问,例如fields.header。当然,您也可以通过编写一个类来封装元组中的信息来完成这一点......再次,如果您愿意的话。如上所示,您始终可以直接对字段进行索引。

    【讨论】:

    • 谢谢,这正是我正在寻找的问候
    【解决方案2】:

    使用struct模块

    【讨论】:

      【解决方案3】:

      这是对您的问题的回答:

      这当然不是最好的方法,因为它不起作用。 struct.unpack() 总是返回一个元组。要提取该元组中的单个项目,您需要执行 field1 = struct.unpack('B',data[0])[0]field1, = struct.unpack('B',data[0])

      即使有这个修复,它也不是一个好方法:输入过多、不必要的 [start:end] 容易出错、10 个函数调用而不是一个函数调用效率低。

      因为你有名字,你可以用它们代替 field1 或 field[0] ...像这样:

      (header, length, typeID, param1, param2,
      param3, param4, name_string, checksum, footer,
      ) = struct.unpack("!2B I 4H 24s I B", data)
      

      【讨论】:

      • 谢谢约翰,更好,非常感谢
      • 感谢您用文字表达感谢。您知道您可以更改您选择的答案吗?
      【解决方案4】:

      这是最好的方法还是有更好的方法

      可能会有其他格式的字符串需要不同的解包方案

      field1 = struct.unpack('B',data[0])
      field2 = struct.unpack('B',data[1])
      field3 = struct.unpack('!I',data[2:6])
      field4 = struct.unpack('!H',data[6:8])
      field5 = struct.unpack('!H',data[8:10])
      field6 = struct.unpack('!H',data[10:12])
      field7 = struct.unpack('!H',data[12:14])
      field8 = struct.unpack('20s',data[14:38])
      field9 = struct.unpack('!I',data[38:42])
      field10 = struct.unpack('B',data[42])

      问候

      【讨论】:

      • 当然有。无需单独获取每个字段。有关示例,请参阅 musicinmybrain 的答案 (stackoverflow.com/questions/1879914/…)。
      • 谢谢,刚刚看到 musicbrains 的回复谢谢大家的时间,非常感谢
      【解决方案5】:

      看看模块'struct'。

      【讨论】:

      • 与@SilentGhost 之前提供的建议相同。
      猜你喜欢
      • 1970-01-01
      • 2016-09-22
      • 2015-04-13
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      相关资源
      最近更新 更多