菜单

Python中二进制数据处理模块struct使用【理财婆高手论坛】

2019年9月5日 - 理财婆高手论坛

Python中没有二进制类型,但是可以使用string字符串类型来存储二进制数据,然后使用struct模块来对二进制数据进行处理。下面将详细描述如何使用struct模块来处理二进制数据。

 

使用struct.pack把一个整数值打包成字符串,打开Python命令行,输入:

 

>>>import struct

 

>>> a =0x01020304

 

>>> str= struct.pack(“I”, a)

 

>>>repr(str)

 

“‘\\x04\\x03\\x02\\x01′”

 

此时,str为一个字符串,字符串中的内容与整数a的二进制存储的内容相同。

 

 

 

使用struct.unpack把字符串解包成整数类型,如下:

 

>>> b =struct.unpack(“I”, str)

 

>>> b

 

(16909060,)

 

在解包之后,返回一个元组类型(tuple)的数据。

 

如果多个数据进行打包,可以在格式中指定打包的数据类型,然后数据通过参数传入:

 

>>> a =”hello”

 

>>> b =”world!”

 

>>> c =2

 

>>> d =45.123

 

>>> str= struct.pack(“5s6sif”, a, b, c, d)

 

等价于: struct.pack_into(“5s6sif”,str,  0, a, b, c, d)

 

>>> str

 

‘helloworld!\x00\x02\x00\x00\x00\xf4}4B’

 

解包多个数据可以这样做:

 

>>>parts = struct.unpack(“5s6sif”, str)

 

等价于:  struct.unpack_from(“5s6sif”, str, 0)

 

>>>parts

 

(‘hello’,’world!’, 2, 45.12300109863281)

 

从上可以看到浮点值在解包后与原来值不一样,这是因为浮点数的精度问题导致的。

 

struct模块中二进制格式化表示

 

格式

 C类型

 Python类型

 字节数

 

x

 填充字节

 无值

 1

 

c

 char

 长度为1的字符串

 1

 

b

 signed char

 整型

 1

 

B

 unsigned char

 整型

 1

 

?

 _bool

 bool

 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[]

 字符串

 1

 

p

 Char[]

 字符串

 1

 

P

 Void *

 long

 4

 

 

最后一个可以用来表示指针类型,占4个字节(32位),8个字节(64位)。

 

为了在与不同硬件结构之间交换数据,需要考虑字节序,如下:

 

字符

 字节序

 大小和对齐

 

@

 本机字节序

 本机,本机4字节对齐

 

=

 本机字节序

 标准,按原字节数对齐

 

 小尾字节序

 标准,按原字节数对齐

 

 大尾字节序

 标准,按原字节对齐

 

!

 网络字节序(大尾)

 标准,按原字节对齐

 

 

注:缺省的情况下,使用本机字节序(同@),可以通过上面的字符修改字节序。

 

计算格式字符串的大小函数:struct.calcsize(fmt)

 

>>>struct.calcsize(“ihi”)                      
缺省为4字节对齐时,长度为12

 

12

 

>>>struct.calcsize(“iih”)                          
 当h在最后的时(此时不4字节对齐),长度为10

 

10

 

>>>struct.calcsize(“@ihi”)

 

12

 

>>>struct.calcsize(“=ihi”)

 

10

 

>>>struct.calcsize(“>ihi”)

 

10

 

>>>struct.calcsize(“<ihi”)

 

10

 

>>>struct.calcsize(“!ihi”)

 

10

 

注:二进制文件打开/读取的时候需要使用“rb”/“wb”模式以二进制方式打开/读取文件。

 

注:关于LE(little-endian)和BE(big-endian)区别:

 

LE—最符合人的思维的字节序,地址低位存储值的低位,地址高位存储值的高位。

 

BE—最直观的字节序,地址低位存储值的高位,地址高位存储值的低位。

 

例如:双字0X01020304在内存中存储方式,LE=0403 02 01,BE=01 02 03 04。

 

 

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图