934 字
5 分钟
struct库
Python struct库
struct模块提供了在 Python 值和 C 结构体之间转换的二进制数据的打包和解包功能。它主要用于处理二进制数据文件、网络协议等场景。struct是python的内置模块,无需额外下载
主要功能
struct模块主要提供以下功能:
- 将Python数据类型打包成二进制字符串
- 将二进制数据解包为Python数据类型
- 处理不同字节序(大端、小端)的数据
大端、小端
给不了解的朋友介绍一下大端和小端
大端Big-endian和小端Little-endian是我们计算机存储多字节数据时采用的不同方式,它们描述了数据在内存中的排列顺序,也就是从左到右或从右到左的顺序。
有趣的是,大端小端的术语其实来自于《格列佛游记》中两个派别关于应该从哪一端打破鸡蛋的争论。
大端Big-endian
- 将数据的高位字节存储在低地址,低位字节存储在高地址
- 更符合人类从左到右的阅读直觉,阅读时先看到高位
小端Little-endian
- 将数据的低位字节存储在低地址,高位字节存储在高地址
- 这种模式对计算机处理起来更方便,因为从低地址开始可以立即处理低位数据
例如:
>>> struct.pack('<I', 900).hex() # 小端'84030000'>>> struct.pack('>I', 900).hex() # 大端'00000384'应用场景
1.硬件架构
- 大部分主流架构如
x86、x86-64、ARM采用小端 - 部分
ARM架构可以配置字节顺序
2.文件格式
- 不同文件格式使用不同字节序
-
PNG、JPEG、GIF:使用大端
-
BMP:使用小端
-
TIFF:可选择大端或小端,在文件头中标识
常用函数
1. struct.pack(fmt, v1, v2, ...)
将值按照指定的格式(fmt)打包成二进制数据。
>>> struct.pack('if', 42, 3.14)b'*\x00\x00\x00\xc3\xf5H@'>>> struct.pack('>i', 900)b'\x00\x00\x03\x84'>>> struct.pack('>i', 900).hex()'00000384'2. struct.unpack(fmt, string)
将二进制数据按照指定的格式(fmt)解包为Python值。
>>> struct.unpack('if', b'*\x00\x00\x00\xc3\xf5H@')(42, 3.140000104904175)>>> struct.unpack('>i', b'\x00\x00\x03\x84')(900,)3. struct.calcsize(fmt)
计算按照给定格式打包后的二进制数据大小(字节数)。
>>> struct.calcsize('if')8>>> struct.calcsize('i')4>>> struct.calcsize('iI')8格式字符
格式字符用于指定数据类型和大小:
| 字符 | C类型 | Python类型 | 大小(字节) |
|---|---|---|---|
c | char | 长度为1的字符串 | 1 |
b | signed char | 整数 | 1 |
B | unsigned char | 整数 | 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[] | 字节串 | |
p | char[] | 字节串 | |
P | void* | 整数 |
字节顺序
格式字符串的第一个字符可以用来指定字节顺序:
| 字符 | 字节顺序 | 对齐方式 |
|---|---|---|
@ | 本机 | 本机 |
= | 本机 | 标准 |
< | 小端 | 标准 |
> | 大端 | 标准 |
! | 网络(大端) | 标准 |
示例应用
处理不同字节序
>>> value = 0x12345678 # 创建一个32位整数 0x12345678>>>>>> struct.pack('<I', value).hex() # 小端'78563412'>>> struct.pack('>I', value).hex() # 大端'12345678'>>> struct.pack('@I', value).hex() # 输出取决于系统架构'78563412'注意事项
对齐问题:默认情况下,struct模块会按照C编译器的对齐规则来打包数据。如果需要精确控制字节位置,可以使用标准大小(如
<、>、!前缀)。字符串处理:使用
s格式字符时,需要指定固定长度,如10s表示10字节的字符串。
struct模块是Python中处理二进制数据的强大工具,特别适合需要与C语言结构体交互、处理二进制文件格式或实现网络协议的场景。通过合理使用格式字符和字节顺序控制,可以高效地在Python值和二进制数据之间进行转换。