18

我正在打开一个二进制文件,如下所示:

file = open("test/test.x", 'rb')

并逐行阅读列表。每一行看起来有点像:

'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'

我很难操纵这些数据。如果我尝试打印每一行,python 会冻结,并发出哔哔声(我认为那里有一个二进制哔声代码)。如何安全地使用这些数据?如何将每个十六进制数转换为十进制?

4

7 回答 7

25

要打印它,您可以执行以下操作:

print repr(data)

对于整个十六进制:

print data.encode('hex')

对于每个字节的十进制值:

print ' '.join([str(ord(a)) for a in data])

要从数据中解压缩二进制整数等,就好像它们最初来自 C 风格的结构一样,请查看struct模块。

于 2010-06-17T06:23:49.777 回答
4

\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)
于 2010-06-17T06:26:57.350 回答
3

二进制数据很少被分成由 '\n' 分隔的“行”。如果是,它将具有隐式或显式转义机制来区分作为行终止符的 '\n' 和作为数据一部分的 '\n'。在不了解转义机制的情况下盲目地读取这样的文件是没有意义的。

回答您的具体问题:

'\x07' 是 ASCII BEL 字符,最初用于在电传打字机上响铃。

你可以通过做得到一个字节'b'的整数值ord(b)

但是,要正确处理二进制数据,您需要知道布局是什么。您可以有有符号和无符号整数(大小为 1、2、4、8 字节)、浮点数、可变长度的十进制数、固定长度的字符串、可变长度的字符串等。增加的复杂性来自是否记录数据以大端方式或小端方式。一旦您了解了以上所有内容(或有很好的猜测),Python struct 模块应该能够用于您的全部或大部分处理;ctypes 模块也可能有用。

数据格式有名称吗?如果有,请告诉我们;我们也许可以将您指向代码或文档。

您问“我如何安全地使用这些数据?” 这就引出了一个问题:你想用它做什么?你想做什么操作?

于 2010-06-17T06:53:35.537 回答
2

就像提到的剧院一样,ord 和 hex 可能会对您有所帮助。如果您想尝试解释文件中的某种结构化二进制数据,struct模块可能会有所帮助。

于 2010-06-17T06:25:28.173 回答
1

您正在尝试打印转换为 ASCII 字符的数据,但这是行不通的。

您可以安全地使用任何字节的数据。如果要将其打印为十六进制,请查看函数ordhex/

于 2010-06-17T06:20:31.277 回答
1

你是用read()还是readline()?您应该使用read(n)读取 n 个字节;readline()将读取直到遇到二进制文件可能没有的换行符。

但是,在任何一种情况下,都会返回一个字节字符串,它可能是可打印的或不可打印的字符,并且可能不是很有用。

您想要的是ord(),它将一个字节的字符串转换为相应的整数值。read()一次从文件中读取一个字节并调用ord()结果,或者遍历整个字符串。

于 2010-06-17T06:29:58.047 回答
0

如果你愿意使用 NumPy 和bitstream,你可以这样做

>>> 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)
于 2018-05-13T11:38:30.723 回答