用 struct 模块可以实现字符串和二进制数据间的相互转换,常用来解析网络数据、C 语言结构体对应的数据。
常用方法
struct.pack(fmt, data1, data2, ...):用于将 Python 的值根据格式字符串转换为 bytes
struct.unpack(fmt, bytes):将 bytes 按照格式字符串给定的格式解析成一个元组。
格式字符串
字节顺序,大小和对齐方式:
| 字符 | 字节顺序 | 大小 | 对齐方式 | 
|---|---|---|---|
@ | 
按原字节 | 按原字节 | 按原字节 | 
= | 
按原字节 | 标准 | 无 | 
< | 
小端 | 标准 | 无 | 
> | 
大端 | 标准 | 无 | 
! | 
网络(=大端) | 标准 | 无 | 
格式字符:
| 格式 | C 类型 | Python 类型 | 标准大小 | 注释 | 
|---|---|---|---|---|
x | 
填充字节 | 无 | ||
c | 
char | 
长度为 1 的字节串 | 1 | |
b | 
signed char | 
整数 | 1 | (1), (2) | 
B | 
unsigned char | 
整数 | 1 | (2) | 
? | 
_Bool | 
bool | 1 | (1) | 
h | 
short | 
整数 | 2 | (2) | 
H | 
unsigned short | 
整数 | 2 | (2) | 
i | 
int | 
整数 | 4 | (2) | 
I | 
unsigned int | 
整数 | 4 | (2) | 
l | 
long | 
整数 | 4 | (2) | 
L | 
unsigned long | 
整数 | 4 | (2) | 
q | 
long long | 
整数 | 8 | (2) | 
Q | 
unsigned long long | 
整数 | 8 | (2) | 
n | 
ssize_t | 
整数 | (3) | |
N | 
size_t | 
整数 | (3) | |
e | 
(6) | float | 2 | (4) | 
f | 
float | 
float | 4 | (4) | 
d | 
double | 
float | 8 | (4) | 
s | 
char[] | 
字节串 | ||
p | 
char[] | 
字节串 | ||
P | 
void * | 
整数 | (5) | 
使用样例
样例一:将 int 转换为 bytes,然后再转换成两个 short
import structbin_num = struct.pack('>i', 65536) # 使用大端模式读入print(bin_num) # b'\x00\x00\x01\x00'print(struct.unpack('>hh', bin_num)) # (1, 0)
样例二:元组和 C 结构体相互转换
'''假设结构体的结构如下:struct header {int buf1;double buf2;char buf3[11];}'''import structbuf1 = xxxbuf2 = xxx.xxxbuf3 = "xxxxxxxxxxx"header = struct.pack('id11s', buf1, buf2, bytes(buf3, encoding='ascii')) # 构造结构体buf1, buf2, buf3 = struct.unpack('id11s', header) # 解包结构体
样例三:实现 OTP 算法(见此文:OTP 介绍与实现)
