[英]Turning binary data into a literal string of '0's and '1's
我有一個充滿二進制數據的文件,該文件表示2字節指令的順序為大端順序。
我需要能夠將這些指令解碼為更有意義的等價物,但是我無法將數據轉換為可以使用的格式。
我認為最好將指令轉換為0和1的實際字符串。
到目前為止,我已經寫了這個:
def slurpInstructions(filename):
instructions = []
with open(filename, 'rb') as f:
while True:
try:
chunk = f.read(1)
print(struct.unpack('c', chunk))
except:
break
一次打印出字節1,如下所示:
(b'\x00',)
(b'a',)
我知道文件中的第一條指令是:
0000000001100001
因此,看起來它正在打印出與每個字節的整數值相對應的ascii字符,除了它只是在沒有int值的ascii char時打印出十六進制表示形式。
不過我從哪里去呢? 我需要將b'a'
變成'1100001'
因為我實際上關心的是位,而不是字節。
您可以將b'a'
轉換為其對應的整數ord
值,然后使用'{:b}'.format
以二進制格式打印int:
In [6]: '{:b}'.format(ord(b'a'))
Out[6]: '1100001'
一次讀取一個大文件可能很慢。 通過對f.read
每次調用讀取更多字節,可以提高性能。 您可以使用以下命令以1024字節的塊迭代文件的內容:
with open(filename, 'rb') as f: for chunk in iter(lambda: f.read(1024), b''):
同樣,為每個字節調用一次print
可能會非常慢。 通過每次調用print
打印更多字節,您將獲得更好的性能。 因此,您可以使用列表推導來遍歷chunk
的字節,將每個字節轉換為其字符串二進制格式,然后使用''.join
將字符串連接在一起:
print(''.join(['{:b}'.format(ord(c)) for c in chunk]), end='')
使用裸except
被認為是不好的做法 。 如果您選擇在此處使用try..except
,請僅列出您要處理的那些異常:
try: ... except IOError:
def slurpInstructions(filename):
with open(filename, 'rb') as f:
for chunk in iter(lambda: f.read(1024), b''):
print(''.join(['{:b}'.format(c) for c in chunk]), end='')
在Python 3中,將2個字節轉換為一個位串( '{:b}'.format()
可能會稍微慢一些 ):
>>> bin(int.from_bytes(b'\x00a', 'big'))[2:].zfill(16)
'0000000001100001'
有關與Python 2/3兼容的單源版本,請參閱將二進制轉換為ASCII,反之亦然
為了既節省時間又節省空間地加載所有指令,可以使用array
模塊 :
#!/usr/bin/env python
import os
import sys
from array import array
instructions = array('H') # each instruction is >=2 bytes
n = os.path.getsize(filename) // instructions.itemsize # number of instructions
with open(filename, 'rb') as file:
instructions.fromfile(file, n) # slurp file
if sys.byteorder == 'little':
instructions.byteswap() # force big-endian order
for h in instructions: # print as bitstrings
print('{:016b}'.format(h))
有關有效讀取二進制文件的其他方式,請參閱使用Python讀取二進制文件並遍歷每個字節 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.