将打包数据解码为结构
将 python 字符串解包到字段中的最佳方法是什么
我从 tcp 套接字接收到数据,它的打包方式如下,我相信它将位于来自套接字 recv 函数的字符串中
它具有以下格式
uint8 - header
uint8 - 长度
uint32 - 类型ID
uint16-param1
uint16-param2
uint16-param3
uint16-param4
char[24] - 名称字符串
uint32 - 校验和
uint8 - 页脚
(我还需要解压与上述格式不同的其他数据包)
我如何解压这些?
我是 python 新手,做过一些“C”。如果我使用“C”,我可能会使用结构体,这会是使用 Python 的方法吗?
问候
X
What would the best way of unpacking a python string into fields
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
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
(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?
Regards
X
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
struct 模块旨在根据格式字符串将异构数据解压缩为元组。一次解压整个结构比尝试一次提取一个字段更有意义。这是一个例子:
然后你可以访问给定的字段,例如第一个字段:
你还可以使用元组来初始化NamedTuple;有关示例,请参阅 struct 文档。 NamedTuples 仅在 Python 2.6+ 中可用,但它们的行为更像 Python 结构,因为您可以将元素作为属性访问,例如 fields.header。当然,您也可以通过编写一个类来封装元组中的信息来完成这一点,如果您关心的话,请再次强调。您始终可以直接索引字段,如我上面所示。
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:
Then you can access a given field, for example the first field:
You could also use the tuple to initialize a NamedTuple; look at the documentation for struct for 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.
使用
struct
模块use
struct
module这是对您的问题作为答案的答案:
这当然不是最好的方法,因为它不起作用。
struct.unpack()
始终返回一个元组。要取出该元组中的单个项目,您需要执行field1 = struct.unpack('B',data[0])[0]
或field1, = struct.unpack ('B',数据[0])
。即使有了这个修复,这也不是一个好方法:输入太多,不必要的 [start:end] 容易出错,10 个函数调用(而不是 1 个)效率低下。
由于您有名称,因此可以使用它们代替 field1 或 field[0] ...,如下所示:
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 eitherfield1 = struct.unpack('B',data[0])[0]
orfield1, = 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.
As you have names, you can use them instead of field1 or field[0] ... like this:
这是执行此操作的最佳方法还是有更好的方法
很可能会有其他格式的字符串需要不同的解包方案
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])
问候
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])
Regards
看一下模块“struct”。
Take a look at the module 'struct'.