对于十六进制的协议,python 中的编写总是会用到 struct.pack 。各种写法,我根本记不住。例如
CodeBlock Loading...
一、字节顺序与对齐(首字符)
格式字符串的第一个字符通常表示字节顺序和对齐方式:
| 字符 | 说明 | 示例 |
|---|---|---|
@ | 默认(本地字节序,无对齐) | @I |
= | 本地字节序,标准大小 | =H |
< | 小端(Little-Endian) | <i |
> | 大端(Big-Endian) | >f |
! | 网络序(等同于大端) | !d |
二、数据类型与大小
| 字符 | C 类型 | Python 类型 | 大小(字节) | 示例 |
|---|---|---|---|---|
x | 填充字节 | 无 | 1 | x |
c | char | 长度为1的字节 | 1 | c |
b | signed char | 整数 | 1 | b |
B | unsigned char | 整数 | 1 | B |
? | _Bool | 布尔值 | 1 | ? |
h | short | 整数 | 2 | h |
H | unsigned short | 整数 | 2 | H |
i | int | 整数 | 4 | i |
I | unsigned int | 整数 | 4 | I |
l | long | 整数 | 4 | l (32位系统) |
L | unsigned long | 整数 | 4 | L (32位系统) |
q | long long | 整数 | 8 | q |
Q | unsigned long long | 整数 | 8 | Q |
f | float | 浮点数 | 4 | f |
d | double | 浮点数 | 8 | d |
s | char[] | 字节串 | 长度由数字前缀指定 | 10s |
p | Pascal字符串 | 字节串 | 长度+1字节(最大255) | p |
P | void* | 整数 | 平台相关 | P |
三、特殊符号
| 字符 | 说明 | 示例 |
|---|---|---|
0 | 填充字节(等同于 x) | 0x |
num | 数字前缀表示重复次数或长度 | 3I 表示打包3个无符号整型 |
_ | 平台本地大小和对齐(需 Python 3.3+) | _d |
四、常用组合示例
打包一个大端 4 字节无符号整型 + 双精度浮点数:
CodeBlock Loading...打包一个带填充的小端结构体(例如
int + char,4 字节对齐):CodeBlock Loading...打包一个固定长度的字符串:
CodeBlock Loading...打包布尔值 + 无符号短整型(网络序):
CodeBlock Loading...
五、注意事项
数值范围验证:
- 例如
B(0~255)、I(0~0xFFFFFFFF),超出范围会报错。 建议在打包前检查数值范围:
CodeBlock Loading...
- 例如
平台差异:
l和L在 32 位系统为 4 字节,64 位系统可能为 8 字节。- 使用
i或I确保固定 4 字节。
字符串处理:
s格式需要明确长度(如10s)。- 若需动态长度字符串,可配合
len()使用:python s = b'hello' data = struct.pack(f'I{len(s)}s', len(s), s)