Python中二進位制資料處理模組struct使用
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。