位置: 文档库 > Python > 详细介绍Python使用struct处理二进制(pack和unpack用法)

详细介绍Python使用struct处理二进制(pack和unpack用法)

张楚 上传于 2024-09-25 20:02

《详细介绍Python使用struct处理二进制(pack和unpack用法)》

在Python中处理二进制数据是许多场景下的核心需求,例如网络通信、文件解析、硬件交互等。二进制数据以紧凑的字节形式存储,但直接操作字节流需要处理字节顺序、数据类型对齐等复杂问题。Python的`struct`模块提供了高效的解决方案,通过`pack`和`unpack`函数将Python基本数据类型与二进制字节相互转换,极大简化了二进制数据的处理流程。

一、struct模块基础

`struct`模块的核心功能是按照指定的格式将Python数据转换为C语言结构的二进制表示(`pack`),或从二进制数据中解析出Python对象(`unpack`)。其核心函数包括:

  • struct.pack(fmt, v1, v2, ...):将Python值按格式`fmt`打包为字节对象
  • struct.unpack(fmt, buffer):从字节对象`buffer`中按格式`fmt`解包为Python元组
  • struct.calcsize(fmt):返回格式`fmt`对应的字节长度

1.1 格式字符串(Format String)

格式字符串由两部分组成:字节序标记和数据类型代码。例如:

'

表示:

  • `
  • `i`:有符号整数(4字节)
  • `i`:有符号整数(4字节)
  • `h`:有符号短整型(2字节)

完整字节序标记:

  • `@`:原生字节序(默认,依赖系统)
  • `=`:原生字节序,标准大小
  • `
  • `>`:大端字节序(Big-endian)
  • `!`:网络字节序(等同于`>`)

常用数据类型代码:

代码 C类型 Python类型 字节数
x 填充字节 1
c char bytes(长度1) 1
b signed char 整数 1
B unsigned char 整数 1
? _Bool 布尔值 1
h short 整数 2
H unsigned short 整数 2
i int 整数 4
I unsigned int 整数 4
l long 整数 4
L unsigned long 整数 4
q long long 整数 8
Q unsigned long long 整数 8
f float 浮点数 4
d double 浮点数 8
s char[] bytes 指定长度
p char[] bytes 指定长度+1(含终止符)
P void * 整数 与系统指针同大小

二、pack函数详解

`pack`函数将Python值转换为二进制字节。其语法为:

struct.pack(fmt, v1, v2, ...)

2.1 基本用法

示例:打包两个整数和一个浮点数

import struct

data = struct.pack('

解释:

  • `
  • 输出为12字节的二进制数据

2.2 处理字符串

打包字符串时需指定长度:

# 打包5字节字符串
packed = struct.pack('

2.3 对齐与填充

某些架构要求数据按特定边界对齐。使用`@`或`=`可启用原生对齐:

# 原生对齐(可能包含填充字节)
packed = struct.pack('@i d', 1, 2.5)
print(len(packed))  # 输出12(4字节int + 4字节填充 + 8字节double)

三、unpack函数详解

`unpack`函数将二进制字节解析为Python元组。其语法为:

struct.unpack(fmt, buffer)

3.1 基本用法

示例:解包之前打包的数据

import struct

packed = b'\n\x00\x00\x00\x14\x00\x00\x00@\t\x1e\xb8'
unpacked = struct.unpack('

3.2 处理变长数据

解包时需确保字节长度与格式匹配:

# 解包错误示例(字节长度不足)
try:
    struct.unpack('

3.3 动态格式字符串

可通过`calcsize`验证格式长度:

fmt = '

四、高级应用场景

4.1 网络协议解析

解析TCP头部的简化示例:

import struct

# TCP头部格式(简化版):源端口(2B)、目的端口(2B)、序列号(4B)
tcp_header = b'\x1f\x90\x08\x00\x12\x34\x56\x78'

src_port, dst_port, seq_num = struct.unpack('!HHI', tcp_header)
print(f"源端口: {src_port}, 目的端口: {dst_port}, 序列号: {seq_num}")
# 输出:源端口: 8080, 目的端口: 2048, 序列号: 305419896

4.2 二进制文件读写

写入和读取自定义二进制文件:

# 写入文件
with open('data.bin', 'wb') as f:
    packed = struct.pack('

4.3 与数组模块结合

处理大量二进制数据时,可结合`array`模块提高效率:

import struct
import array

# 生成100个浮点数
floats = (i * 0.1 for i in range(100))

# 打包为二进制
packed = b''.join(struct.pack('

五、常见问题与解决方案

5.1 字节序问题

不同系统可能使用不同字节序,网络通信中建议统一使用大端序:

# 明确指定网络字节序
data = struct.pack('!I', 0x12345678)
print(data)  # 输出:b'\x124Vx'(大端序)

5.2 浮点数精度

浮点数打包解包可能存在精度损失:

original = 3.141592653589793
packed = struct.pack('

5.3 性能优化

对于大量数据,避免循环调用`pack`/`unpack`:

# 低效方式
results = []
for i in range(1000):
    results.append(struct.pack('

六、完整示例:自定义二进制协议

设计一个包含头部和数据的简单协议:

import struct

# 协议格式:
# 魔数(4B) | 版本(1B) | 类型(1B) | 数据长度(2B) | 数据(...)
PROTOCOL_FMT = '

关键词:Python、struct模块二进制处理、pack函数、unpack函数格式字符串、字节序、网络协议、数据解析、性能优化

简介:本文详细介绍了Python中struct模块处理二进制数据的方法,重点讲解了pack和unpack函数的用法,包括格式字符串的组成、字节序控制、数据类型转换等核心概念。通过实际案例展示了在网络协议解析、二进制文件读写等场景中的应用,并提供了常见问题的解决方案和性能优化技巧。

《详细介绍Python使用struct处理二进制(pack和unpack用法).doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档