在 Python 中操作二进制数据
-
28-09-2019 - |
题
我正在打开一个二进制文件,如下所示:
file = open("test/test.x", 'rb')
并逐行阅读列表。每行看起来都有点像:
'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
我很难操纵这些数据。如果我尝试打印每一行,python 就会冻结,并发出嘟嘟声(我认为某处有一个二进制嘟嘟声代码)。我如何安全地使用这些数据?如何将每个十六进制数转换为十进制数?
解决方案
要打印它,您可以执行以下操作:
print repr(data)
对于整个十六进制:
print data.encode('hex')
对于每个字节的十进制值:
print ' '.join([str(ord(a)) for a in data])
解压二进制整数等。从数据来看,就好像它们最初来自 C 风格的结构一样,看看 结构体 模块。
其他提示
\xhh
与十六进制值HH 的字符。其它字符,如.
和'〜”是普通字符。
迭代上的串给你字符它,一次一个。
ord(c)
将返回一个表示字符的整数。例如,ord('A') == 65
。
这将打印十进制数的每个字符:
s = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
print ' '.join(str(ord(c)) for c in s)
像theatrus提到,ORD和六角可能会帮助你。 如果您想尝试解释某种结构化的二进制数据的文件中,则结构模块可能是有益的。
二进制数据中很少分为“线”由分隔“\ N”。如果是,它将具有隐式或显式的擒纵机构作为一个行结束和“\ n”作为数据的一部分的“\ N”之间进行区分。读取这样的文件为盲目行没有逃逸机制的知识是没有意义的。
要回答你的具体问题:
“\ X07”是ASCII BEL字符,这原本用于振铃的电传打字机上的钟形。
您可以通过执行ord(b)
得到一个字节“B”的整数值。
但是,要正确处理二进制数据,你需要知道的布局内容。可以有符号和无符号整数,浮点数,不同长度的十进制数字的,固定长度字符串,可变长度字符串,等等等等添加并发症来自数据是否要被记录(尺寸1,2,4,8个字节的)在大尾端方式或littleendian时尚。一旦你知道了以上所有的(或有很好的知情猜测),则 Python的结构模块一>应该能够用于所有或大多数的处理;的 ctypes的模块也可能是有用的。
是否数据格式有名字吗?如果是这样,请告诉我们;我们可以能够您指向代码或文档。
您问“我怎么去安全地使用这些数据?”这引出了一个问题:你想要什么用它来做什么?什么操作你想干什么?
您要打印的数据转换成ASCII字符,这是行不通的。
您可以安全地使用任何数据字节。如果你想打印为十六进制,看看功能ord
和hex
/
您使用read()
或readline()
?你应该用read(n)
读取n个字节; readline()
将读取直到碰到换行,其二进制文件可能没有。
在任一情况下,虽然,将返回的字节串,其可以是可打印的或不可打印的字符,并且可能不是非常有用的。
你想要的是ord()
,它转换一字节串为相应的整数值。从通过整个字符串在上的结果的时间和呼叫read()
文件一个字节,或者iterate ord()
。
如果您愿意使用与NumPy和流,你可以做
>>> from numpy import *
>>> from bitstream import BitStream
>>> raw = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
>>> stream = BitStream(raw)
>>> stream.read(raw, uint8, len(stream) // 8)
array([190, 0, 200, 100, 248, 100, 8, 228, 46, 7, 126, 3, 158,
7, 190, 3, 222, 7, 254, 10], dtype=uint8)