![](/img/trans.png)
[英]How can I read a block from a binary file and extract structs using unpack using Python or Perl?
[英]How to unpack from a binary file a byte array using Python?
我正在給自己一個使用Python讀取二進制文件的速成課程。 我是兩個人的新手,所以請耐心等待我。
文件格式的文檔告訴我前16個字節是一個GUID,進一步閱讀告訴我這個GUID格式化如下:
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
byte Data4[8];
} GUID,
UUID,
*PGUID;
到目前為止,我已經能夠解析結構中的前三個條目了,但我對#4感到難過。 它是一個8字節的數組我想,但我不知道如何打開它。
import struct
fp = open("./file.bin", mode='rb')
Data1 = struct.unpack('<L', fp.read(4)) # unsigned long, little-endian
Data2 = struct.unpack('<H', fp.read(2)) # unsigned short, little-endian
Data3 = struct.unpack('<H', fp.read(2)) # unsigned short, little-endian
Data4 = struct.unpack('<s', bytearray(fp.read(8))) # byte array with 8 entries?
struct.error: unpack requires a bytes object of length 1
我對Data4做錯了什么? (我使用的是Python 3.2 BTW)
Data1到3都可以。 如果我對它們使用hex(),我會得到我期望看到的正確數據(哇哇)我只是對這個字節數組的語法失敗了。
編輯:答案
我正在讀取MS-DTYP中定義的GUID並將其釘入:
data = uuid.UUID(bytes_le=fp.read(16))
如果你想要一個8字節的字符串,你需要將數字8
放在那里:
struct.unpack('<8s', bytearray(fp.read(8)))
來自文檔 :
格式字符之前可以是整數重復計數。 例如,格式字符串'4h'表示與'hhhh'完全相同。
...
對於's'格式字符,計數被解釋為字節的長度,而不是像其他格式字符那樣的重復計數; 例如,'10s'表示單個10字節字符串,而'10c'表示10個字符。 如果未給出計數,則默認為1.對於打包,字符串將被截斷或填充為適當的空字節以使其適合。 對於解包,生成的字節對象始終具有指定的字節數。 作為一種特殊情況,'0'表示單個空字符串(而'0c'表示0個字符)。
但是,我不確定你為什么要這樣做。
fp.read(8)
為您提供一個8字節的bytes
對象。 你想要一個8字節的bytes
對象。 所以,就這樣做:
Data4 = fp.read(8)
將bytes
轉換為bytearray
除了生成可變副本之外沒有任何效果。 解壓縮它只會返回您開始使用的相同bytes
的副本。 所以為什么?
嗯,實際上, struct.unpack
返回一個tuple
,其中一個值是您開始使用的相同bytes
的副本,但您可以使用以下命令執行此操作:
Data4 = (fp.read(8),)
這就提出了為什么首先需要四個單元素元組的問題。 你將無緣無故地在所有地方做Data1[0]
等。 為什么不呢?
Data1, Data2, Data3, Data4 = struct.unpack('<LHH8s', fp.read(16))
當然,如果這是為了閱讀UUID,那么使用“包含電池”總是比使用鎳和鎘礦石制造自己的電池更好。 正如icktoofay所說,只需使用uuid
模塊:
data = uuid.UUID(bytes_le=fp.read(16))
但請記住,Python的uuid
使用4-2-2-1-1-6格式,而不是4-2-2-8格式。 如果你真的需要這種格式,你需要轉換它,這意味着無論如何要么struct
還是位。 (微軟的GUID通過使用4-2-2-2-6格式使事情變得更加有趣,這兩種格式都不同,並代表原生端的前3個和大端的最后兩個,因為它們喜歡讓事情變得簡單......)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.