python 将打包数据解码为结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1879914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:16:25  来源:igfitidea点击:

Decoding packed data into a structure

pythonstringunpack

提问by mikip

What would the best way of unpacking a python string into fields

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

I have data received from a tcp socket, it is packed as follows, I believe it will be in a string from the socket recv function

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

It has the following format

它具有以下格式

uint8 - header
uint8 - length
uint32 - typeID
uint16 -param1
uint16 -param2
uint16 -param3
uint16 -param4
char[24] - name string
uint32 - checksum
uint8 - footer

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

(I also need to unpack other packets with different formats to the above)

(我还需要将其他格式与上述不同的数据包解包)

How do I unpack these?

我如何解压这些?

I am new to python, have done a bit of 'C'. If I was using 'C' I would probably use a structure, would this be the way to go with Python?

我是python的新手,做过一些'C'。如果我使用“C”,我可能会使用一个结构,这会是 Python 的方式吗?

Regards

问候

X

X

回答by musicinmybrain

The struct module is designed to unpack heterogeneous data to a tuple based on a format string. It makes more sense to unpack the whole struct at once rather than trying to pull out one field at a time. Here is an example:

struct 模块旨在根据格式字符串将异构数据解包为元组。一次解压整个结构比试图一次拉出一个字段更有意义。下面是一个例子:

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

Then you can access a given field, for example the first field:

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

fields[0]

You could also use the tuple to initialize a NamedTuple; look at the documentation for structfor an example. NamedTuples are only available in Python 2.6+, but they behave more like Python structures in that you can access elements as attributes, e.g. fields.header. Of course, you could also accomplish this with a little more work by writing a class to encapsulate the information from the tuple... again, if you care. You can always just index into fields directly, as I showed above.

您还可以使用元组来初始化 NamedTuple;以 struct文档为例。NamedTuples 仅在 Python 2.6+ 中可用,但它们的行为更像 Python 结构,因为您可以将元素作为属性访问,例如 fields.header。当然,您也可以通过编写一个类来封装元组中的信息,通过更多的工作来实现这一点……如果您关心的话,同样如此。你总是可以直接索引字段,就像我上面展示的那样。

回答by John Machin

This is an answer to your question-as-an-answer:

这是对您的问题的回答:

It certainly can't be the best way, because it DOESN'T WORK. struct.unpack()always returns a tuple. To pluck out the single item in that tuple, you need to do either field1 = struct.unpack('B',data[0])[0]or field1, = struct.unpack('B',data[0]).

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

Even with that fix, it's not a good way: too much typing, error proneness of unnecessary [start:end], inefficiency of 10 function calls instead of one.

即使有了这个修复,这也不是一个好方法:打字太多,不必要的 [start:end] 容易出错,10 个函数调用效率低下而不是 1 个。

As you have names, you can use them instead of field1 or field[0] ... like this:

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

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

回答by SilentGhost

use structmodule

使用struct模块

回答by mikip

Is this the best way of doing this or is there a better way

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

It is likely that there will be strings with other formats which will require a different unpacking scheme

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

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])

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])

Regards

问候

回答by RoMa

Take a look at the module 'struct'.

看看模块“ struct”。