首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在python结构中解压缩可变长度数据

如何在python结构中解压缩可变长度数据
EN

Stack Overflow用户
提问于 2015-12-06 12:52:01
回答 2查看 1.9K关注 0票数 1

我正在构建一个p2p应用程序,在这里我需要从跟踪器中解压udp公告响应。

代码语言:javascript
复制
announce response:

Offset      Size            Name            
0           32-bit integer  action        
4           32-bit integer  transaction_id
8           32-bit integer  interval
12          32-bit integer  leechers
16          32-bit integer  seeders
20 + 6 * n  32-bit integer  IP address
24 + 6 * n  16-bit integer  TCP port
20 + 6 * N

我需要从上表中读取name字段中列出的所有数据,但是种子器、ip地址和端口的值是可变的。

如何使用python正确地从响应中解压所有数据?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-06 14:18:18

struct模块对于解压缩二进制数据非常有用。

代码语言:javascript
复制
action, transaction_id, interval, leechers, seeders = struct.unpack('>iiiii', announse_response)

然后,您必须遍历其余的数据,以获得所有ip/端口数据:

代码语言:javascript
复制
ip_port_list = []
while True:
    try: ip_port_list.append(struct.unpack('>ih', announse_response))
    except: break

如果没有struct,您将不得不逐字节读取,然后转换大的endian问题。

票数 1
EN

Stack Overflow用户

发布于 2022-05-18 22:31:29

我也经历过同样的挣扎,所以为此编写了一个简单的包,名为联读

代码语言:javascript
复制
from binread import formatclass, U32, U16, Array 

@formatclass
class Seeder:
    ip_addr = U32
    tcp_port = U16

@formatclass
class AnnounceResponse:
    action = U32
    transaction_id = U32
    interval = U32
    leechers = U32
    seeders = U32

    # `length` refers to the value of the previous `seeders` field
    seeder_data = Array(Seeder, length="seeders")

# `data` is a bytes object
resp = AnnounceResponse.read(data)

print(resp.transaction_id)
print(len(resp.seeder_data))
print(resp.seeder_data[0].tcp_port)

您可以选择使用@formatclass(byteorder='little') (或'big')为所有值指定endianness。

完全公开,我是宾读的作者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34117620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档