struct
struct 按指定格式在 Python 值和字节序列之间转换,适合协议头、文件格式、设备数据和 C 结构体互操作。
pack 与 unpack
import struct
data = struct.pack(">Ih", 1024, -3)
print(data.hex())
number, offset = struct.unpack(">Ih", data)
print(number, offset)
格式中的 > 表示大端序,I 是无符号 4 字节整数,h 是有符号 2 字节整数。常用前缀:< 小端、> 大端、! 网络字节序、= 本机字节序但使用标准大小、@ 本机布局(默认)。跨平台协议应明确使用 <、> 或 !。
格式字符
| 字符 | Python 类型 | 标准大小 |
|---|---|---|
x | 填充字节 | 1 |
c | 单字节 bytes | 1 |
? | 布尔值 | 1 |
b/B | 有符号/无符号字节 | 1 |
h/H | 有符号/无符号短整数 | 2 |
i/I | 有符号/无符号整数 | 4 |
q/Q | 有符号/无符号长整数 | 8 |
f/d | 单/双精度浮点数 | 4/8 |
s | 固定长度字节串 | 前缀指定 |
struct.calcsize(">Ih") 可得到布局大小。10s 表示恰好 10 字节,短字符串会补零,长字符串会截断。
流式读取与校验
record = struct.Struct("<I20s")
with open("records.bin", "rb") as file:
while chunk := file.read(record.size):
if len(chunk) != record.size:
raise ValueError("文件末尾记录不完整")
ident, name = record.unpack(chunk)
print(ident, name.rstrip(b"\\0").decode("utf-8"))
iter_unpack(format, buffer) 可按固定步长迭代。解析不可信数据前检查长度、范围和协议版本;struct 只负责布局转换,不负责校验业务语义,也不应直接执行字节中的内容。