準確地講,Python沒有專門處理字節(jié)的數(shù)據(jù)類型。但由于str既是字符串,又可以表示字節(jié),所以,字節(jié)數(shù)組=str。而在C語言中,我們可以很方便地用struct、union來處理字節(jié),以及字節(jié)和int,float的轉(zhuǎn)換。
在Python中,比方說要把一個32位無符號整數(shù)變成字節(jié),也就是4個長度的str,你得配合位運算符這么寫:
>>> n = 10240099>>> b1 = chr((n & 0xff000000) >> 24)>>> b2 = chr((n & 0xff0000) >> 16)>>> b3 = chr((n & 0xff00) >> 8)>>> b4 = chr(n & 0xff)>>> s = b1 + b2 + b3 + b4>>> s'/x00/x9c@c'
非常麻煩。如果換成浮點數(shù)就無能為力了。
好在Python提供了一個struct模塊來解決str和其他二進制數(shù)據(jù)類型的轉(zhuǎn)換。
struct的pack函數(shù)把任意數(shù)據(jù)類型變成字符串:
>>> import struct>>> struct.pack('>I', 10240099)'/x00/x9c@c'
pack的第一個參數(shù)是處理指令,'>I'的意思是:
>表示字節(jié)順序是big-endian,也就是網(wǎng)絡(luò)序,I表示4字節(jié)無符號整數(shù)。
后面的參數(shù)個數(shù)要和處理指令一致。
unpack把str變成相應的數(shù)據(jù)類型:
>>> struct.unpack('>IH', '/xf0/xf0/xf0/xf0/x80/x80')(4042322160, 32896)
根據(jù)>IH的說明,后面的str依次變?yōu)镮:4字節(jié)無符號整數(shù)和H:2字節(jié)無符號整數(shù)。
所以,盡管Python不適合編寫底層操作字節(jié)流的代碼,但在對性能要求不高的地方,利用struct就方便多了。
struct模塊定義的數(shù)據(jù)類型可以參考Python官方文檔:
https://docs.python.org/2/library/struct.html#format-characters
Windows的位圖文件(.bmp)是一種非常簡單的文件格式,我們來用struct分析一下。
首先找一個bmp文件,沒有的話用“畫圖”畫一個。
讀入前30個字節(jié)來分析:
>>> s = '/x42/x4d/x38/x8c/x0a/x00/x00/x00/x00/x00/x36/x00/x00/x00/x28/x00/x00/x00/x80/x02/x00/x00/x68/x01/x00/x00/x01/x00/x18/x00'
BMP格式采用小端方式存儲數(shù)據(jù),文件頭的結(jié)構(gòu)按順序如下:
兩個字節(jié):'BM'表示W(wǎng)indows位圖,'BA'表示OS/2位圖;
一個4字節(jié)整數(shù):表示位圖大小;
一個4字節(jié)整數(shù):保留位,始終為0;
一個4字節(jié)整數(shù):實際圖像的偏移量;
一個4字節(jié)整數(shù):Header的字節(jié)數(shù);
一個4字節(jié)整數(shù):圖像寬度;
一個4字節(jié)整數(shù):圖像高度;
一個2字節(jié)整數(shù):始終為1;
一個2字節(jié)整數(shù):顏色數(shù)。
所以,組合起來用unpack讀取:
>>> struct.unpack('<ccIIIIIIHH', s)('B', 'M', 691256, 0, 54, 40, 640, 360, 1, 24)
結(jié)果顯示,'B'、'M'說明是Windows位圖,位圖大小為640x360,顏色數(shù)為24。
新聞熱點
疑難解答
圖片精選