【问题标题】:pythonic way to hex dump files十六进制转储文件的pythonic方法
【发布时间】:2014-07-28 22:42:33
【问题描述】:

我的问题很简单:

有没有办法以 bash 命令的 Python 方式进行编码?

hexdump -e '2/1 "%02x"' file.dat

显然,不使用 os、popen 或任何快捷方式;)

编辑:虽然我没有明确指定,但如果代码在 Python3.x 中可以正常工作,那就太好了

谢谢!

【问题讨论】:

  • 2/1 "%02x" 是什么意思?
  • "%02x" 将每个字节打印为 2 个字符,0 前缀大写十六进制数字。
  • 那么2/1 呢?对于那些了解 Python 但现在熟悉 hexfump cli 的人来说,这个问题会更清楚。
  • 看一看:256.com/gray/docs/misc/hexdump_manual_how_to.html >> "一个交互计数,如果不提供,则默认为 1,但如果您需要字节计数,则必须提供。这告诉了多少次在我们打印结束字符串之前进行转换。所以如果你要解码 4 个东西,每个 1 个字节,你会说 4/1。"

标签: python hexdump


【解决方案1】:

如果您只关心 Python 2.x,line.encode('hex') 会将一大块二进制数据编码为十六进制。所以:

with open('file.dat', 'rb') as f:
    for chunk in iter(lambda: f.read(32), b''):
        print chunk.encode('hex')

(IIRC,hexdump 默认每行打印 32 对十六进制;如果没有,只需将 32 更改为 16 或其他任何内容...)

如果两个参数iter看起来莫名其妙,点击帮助链接;一旦你有了想法,它就不会太复杂了。

如果您关心 Python 3.x,encode 仅适用于将 Unicode 字符串转换为字节的编解码器;任何以其他方式转换(或任何其他组合)的编解码器,您必须使用codecs.encode 明确地执行此操作:

with open('file.dat', 'rb') as f:
    for chunk in iter(lambda: f.read(32), b''):
        print(codecs.encode(chunk, 'hex'))

或者使用hexlify可能会更好:

with open('file.dat', 'rb') as f:
    for chunk in iter(lambda: f.read(32), b''):
        print(binascii.hexlify(chunk))

如果您除了打印它们之外还想做一些事情,而不是将整个文件读入内存,您可能需要创建一个迭代器。你可以把它放在一个函数中,然后把print改成yield,这个函数就会返回你想要的迭代器。或使用genexpr 或map 调用:

with open('file.dat', 'rb') as f:
    chunks = iter(lambda: f.read(32), b'')
    hexlines = map(binascii.hexlify, chunks)

【讨论】:

  • 没有一个答案涉及如何实现第二部分,即-e '2/1 "%02x
【解决方案2】:

标准库是您的朋友。试试binascii.hexlify()

【讨论】:

    【解决方案3】:

    只需read() 整个文件和encode('hex')。还有什么比 Pythonic 更好的呢?

    with open('file.dat', 'rb') as f:
        hex_content = f.read().encode('hex')
    

    【讨论】:

    • 除非你几乎肯定想在rb 模式下打开它,这样它就不会翻译换行符。此外,这是特定于 Python 2 的;在 Python 3 中,你不能 encode 字节。仍然 +1。
    • 很好的方法,它有效,但仅在 python2 中。这是 Py3.4 中的输出:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xac in position 0: invalid start byte
    • @peluzza:你需要 Python 3 吗?
    • 好吧,我正在尽最大努力只为 3.X 编写代码,但差距如此之大,不仅适用于十六进制转储;)
    • @peluzza:请参阅 Raymond Hettinger 的回答,如果您需要更多详细信息,请参阅我的回答。
    猜你喜欢
    • 1970-01-01
    • 2016-10-19
    • 2014-11-11
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多