2011-01-23 15 views
4

我想使用Python 3從文件中得到確切的位數序列。有幾個關於這個主題的問題很接近,但並不完全回答它。到目前爲止,我有這樣的:在Python中獲取原始二進制文件的表示形式

>>> data = open('file.bin', 'rb').read() 
>>> data 
'\xa1\xa7\xda4\x86G\xa0!e\xab7M\xce\xd4\xf9\x0e\x99\xce\xe94Y3\x1d\xb7\xa3d\xf9\x92\xd9\xa8\xca\x05\x0f$\xb3\xcd*\xbfT\xbb\x8d\x801\xfanX\x1e\xb4^\xa7l\xe3=\xaf\x89\x86\xaf\x0e8\xeeL\xcd|*5\xf16\xe4\xf6a\xf5\xc4\xf5\xb0\xfc;\xf3\xb5\xb3/\x9a5\xee+\xc5^\xf5\xfe\xaf]\xf7.X\x81\xf3\x14\xe9\x9fK\xf6d\xefK\x8e\xff\x00\x9a>\xe7\xea\xc8\x1b\xc1\x8c\xff\x00D>\xb8\xff\x00\x9c9...' 

>>> bin(data[:][0]) 
'0b11111111' 

OK,我可以得到一個基本數2,但我不明白爲什麼數據[:] [X],我仍然有領先0B。我似乎也必須遍歷整個字符串並進行一些轉換和解析才能獲得正確的輸出。有沒有簡單的方法來獲得01的序列沒有循環,解析和連接字符串?

在此先感謝!

+3

讀取以二進制模式打開的文件會生成字節對象,而不是字符串對象。你確定你使用py3k嗎? – SilentGhost 2011-01-23 18:03:22

+0

是的,我確定我正在使用py3k。它們可能是字節對象,但終端用單引號顯示它們。 – maximus 2011-01-23 18:09:06

回答

5

我會先預先計算的字符串表示的所有值0..255

bytetable = [("00000000"+bin(x)[2:])[-8:] for x in range(256)] 

或者,如果你在LSB到MSB順序寧願位

bytetable = [("00000000"+bin(x)[2:])[-1:-9:-1] for x in range(256)] 

然後在二進制整個文件可以用

binrep = "".join(bytetable[x] for x in open("file", "rb").read()) 
2

這是不是很清楚什麼位序列的意思是。我認爲從字節0開始比特0開始是最自然的,但實際上取決於你想要的。

因此,這裏是一些代碼訪問字節0開始位0位的序列:

def bits_from_char(c): 
    i = ord(c) 
    for dummy in range(8): 
     yield i & 1 
     i >>= 1 

def bits_from_data(data): 
    for c in data: 
     for bit in bits_from_char(c): 
      yield bit 

for bit in bits_from_data(data): 
    # process bit 

(另注:你不需要data[:][0]在你的代碼只需data[0]會做的伎倆,但不首先拷貝整個字符串。)

2

如果你都OK使用外部模塊獲得,這裏採用bitstring

>>> import bitstring 
>>> bitstring.BitArray(filename='file.bin').bin[2:] 
'110000101010000111000010101001111100...' 

就是這樣。它只需要整個文件的二進制字符串表示形式,並僅切掉一個初始'0b'。

1

要原始二進制數據如b'\xa1\xa7\xda4\x86'轉換成表示該數據作爲在Python 3在二進制系統(基數2)的數位串:

>>> data = open('file.bin', 'rb').read() 
>>> bin(int.from_bytes(data, 'big'))[2:] 
'1010000110100111110110100011010010000110...' 

參見Convert binary to ASCII and vice versa

相關問題