Python中使用struct处理二进制字节数据
一、struct
简介
Python没有专门处理字节的数据类型。
但由于b'str'
可以表示字节,所以,字节数组=二进制str
。
而在C语言中,我们可以很方便地用struct
、union
来处理字节,以及字节和int,float
的转换。
在某些场合下,我们需要使用Python处理C语言中的结构体。比如存取文件,socket操作。
为了解决Python中的二进制解码问题,Python中提供了内建模块struct
处理二进制(pack
和unpack
用法)
尽管Python不适合编写底层操作字节流的代码,但在对性能要求不高的地方,利用struct
就方便多了。
二、常用方法
struct
中有三个函数比较重要:
# 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
pack(fmt, v1, v2, ...)
# 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
unpack(fmt, string)
# 计算给定的格式(fmt)占用多少字节的内存
calcsize(fmt)
fmt
中支持的格式为:
FORMAT | C TYPE | PYTHON TYPE | STANDARD SIZE | NOTES |
---|---|---|---|---|
x | pad byte | no value | - | - |
c | char | string of length 1 | 1 | - |
b | signed char | integer | 1 | (3) |
B | unsigned char | integer | 1 | (3) |
? | _Bool | bool | 1 | (1) |
h | short | integer | 2 | (3) |
H | unsigned short | integer | 2 | (3) |
i | int | integer | 4 | (3) |
I | unsigned int | integer | 4 | (3) |
l | long integer | 4 | (3) | - |
L | unsigned long | integer | 4 | (3) |
q | long long | integer | 8 | (2), (3) |
Q | unsigned long long | integer | 8 | (2), (3) |
f | float | float | 4 | (4) |
d | double | float | 8 | (4) |
s | char[] | string | - | - |
p | char[] | string | - | - |
P | void * | integer | - | (5), (3) |
三、使用方法
1、打包(pack
)
struct
的pack
函数把任意数据类型变成bytes
。
import struct
struct.pack('>I', 10240099)
# b'\x00\x9c@c'
pack
的第一个参数'>I'
是处理指令, >
表示字节顺序是big-endian
,也就是网络序,I
表示4字节无符号整数。
后面的参数个数要和处理指令一致。
2、解包(unpack
)
unpack
把bytes
变成相应的数据类型。
struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')
# (4042322160, 32896)
根据>IH
的说明,后面的bytes
依次变为I
:4字节无符号整数和H
:2字节无符号整数。