在Python中操作二进制数据
我正在以这种方式打开一个二进制文件:
file = open("test/test.x", 'rb')
然后把每一行读入一个列表。每一行看起来像这样:
'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
我在处理这些数据时遇到了困难。如果我尝试打印每一行,Python 就会卡住,还会发出嘟嘟声(我觉得里面可能有二进制的嘟嘟声代码)。我该如何安全地使用这些数据呢?我该如何把每个十六进制数字转换成十进制呢?
7 个回答
二进制数据通常不会像文本那样被分成用'\n'分隔的“行”。如果它真的被分成了行,那么会有一种隐含或明确的转义机制来区分'\n'是行结束符还是数据的一部分。盲目地将这样的文件按行读取,而不理解转义机制,是没有意义的。
针对你具体的疑问:
'\x07'是ASCII中的BEL字符,最初是用来在电传打字机上响铃的。
你可以通过 ord(b)
来获取一个字节'b'的整数值。
但是,要正确处理二进制数据,你需要了解数据的结构。你可能会遇到有符号和无符号的整数(大小为1、2、4、8字节),浮点数、不同长度的小数、固定长度的字符串、可变长度的字符串等等。更复杂的是,数据可能是以大端序或小端序的方式记录的。一旦你了解了这些(或者有很好的猜测),那么 Python的struct模块应该能帮助你处理大部分数据;ctypes模块也可能会有用。
这个数据格式有名字吗?如果有,请告诉我们;我们可能能指引你找到相关的代码或文档。
你问“我该如何安全地使用这些数据?”这就引出了一个问题:你想用这些数据做什么?你想进行什么样的操作?
\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)
要打印它,你可以这样做:
print repr(data)
如果想要整个内容以十六进制的形式显示:
print data.encode('hex')
如果想要每个字节的十进制值:
print ' '.join([str(ord(a)) for a in data])
如果你想从数据中提取二进制整数等,就像它们最开始是来自C语言风格的结构体一样,可以看看 struct 模块。