【问题标题】:Manipulating binary data in Python在 Python 中处理二进制数据
【发布时间】:2011-03-04 19:27:23
【问题描述】:

我正在像这样打开一个二进制文件:

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

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

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

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

【问题讨论】:

    标签: python python-2.7 binary hex


    【解决方案1】:

    您正在尝试打印转换为 ASCII 字符的数据,这将不起作用。

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

    【讨论】:

      【解决方案2】:

      要打印它,你可以这样做:

      print repr(data)
      

      对于整个十六进制:

      print data.encode('hex')
      

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

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

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

      【讨论】:

      • 谢谢!这就是我要找的东西!
      【解决方案3】:

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

      【讨论】:

      • +1 表示结构。解释打包二进制数据的正确方法。
      【解决方案4】:

      \xhh is the character with hex value hh. 和 `~' 等其他字符都是普通字符。

      对字符串进行迭代会为您提供其中的字符,一次一个。

      ord(c) will return an integer representing the character. 例如,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)
      

      【讨论】:

      • 请注意 \x07 是那个 ASCII BEL 字符。这就是导致哔哔声的原因。
      【解决方案5】:

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

      不过,无论哪种情况,都会返回一个字节字符串,它可能是可打印或不可打印的字符,并且可能不是很有用。

      你想要的是ord(),它将一个字节的字符串转换成对应的整数值。 read() 一次从文件中提取一个字节,然后在结果上调用 ord(),或者遍历整个字符串。

      【讨论】:

        【解决方案6】:

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

        回答您的具体问题:

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

        你可以通过ord(b)获取字节'b'的整数值。

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

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

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

        【讨论】:

          【解决方案7】:

          如果你愿意使用 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)
          

          【讨论】:

            猜你喜欢
            • 2011-02-04
            • 1970-01-01
            • 2011-08-16
            • 2011-06-24
            • 1970-01-01
            • 2011-08-18
            • 2017-05-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多