python使用struct模块打包和解包

python中的struct模块可用于将“python类型值”与“python字符串形式的C结构体”互相转换。

格式字符串

当将一个或一组python类型值打包成字符串形式的C结构体时,需要用到一个格式字符串。格式字符串用于定义在打包或解包时python类型,还可以指明字节序、类型占用字节的大小和对齐方式等。

常用格式字符列表

以下是一些常用的数据类型,更多详细的内容参考struct文档

Format C Type Python type Standard size
c char bytes of length 1 1
b signed char integer 1
B unsigned char integer 1
h short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
f float float 4
d double float 8
s char[] bytes
p char[] bytes

注意以下几点:

  • 当将python中的一个非整数类型转换为整数打包时,如果该类型定义有__index()__方法,则会调用该方法将类型转化为整数后再打包。
  • 对于格式 'f''d' ,打包时会分别使用IEEE 754 的binary32和 binary64格式。
  • 格式字符可以配合表示重复次数的整数来使用,如格式字符串 '4h''hhhh'表示相同的含义。

特殊控制符号

以下是格式字符串支持的特殊控制符号及对应控制的内容:

Character Byte order Size Alignment
@ native native native
= native standard none
< little-endian standard none
> big-endian standard none
! network (= big-endian) standard none

当未使用上述字符时,则默认使用的是 '@'

pack、unpack和calcsize

pack

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

用于打包数据,会返回按照格式字符串fmt打包的包含值v1,v2,...的字节对象,提供的参数应当与格式字符串所要求的匹配。

unpack

struct.unpack(fmt, buffer)

根据格式字符串fmt迭代解包出buffer的内容,此函数会返回一个迭代器,该迭代器会从buffer中读取相同大小的数据块,直到所有内容都被用完。buffer以字节为单位的大小必须是fmt对应的格式的字节大小的整数倍。每次迭代都会产生一个由格式字符串定义的元组。

calcsize

struct.calcsize(fmt)

返回与格式字符串fmt相对应的结构体的大小,也是使用此格式字符串打包出来的字节对象的大小。

以下是一个简单的示例:

1
2
3
4
5
6
7
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8

REFERENCE

https://docs.python.org/3/library/struct.html