【问题标题】:Python: How to compare two binary files?Python:如何比较两个二进制文件?
【发布时间】:2017-07-26 13:58:55
【问题描述】:

在 python 中,我需要打印两个二进制文件的差异。我在看difflib.Differ,它做了很多。

但假设文本行不同,因此输出不会列出字节索引和十六进制值的差异。

我需要的是输出有什么不同的字节,字节如何不同,两个字节的实际十六进制值。

在Python中,如何比较两个二进制文件(输出:字节差异索引,两个字节的十六进制值)?

我正在做类似的事情:

# /usr/bin/env python2
import difflib
x = open('/path/to/file1', 'r').read()
y = open('/path/to/file2', 'r').read()
print '\n'.join(difflib.Differ().compare(x, y))

但这不会输出差异所在的字节索引。而且它不打印十六进制值。

【问题讨论】:

  • 我也可以不使用difflib。但我觉得应该有一个使用difflib 的优雅解决方案。
  • 我刚刚阅读了手册页man 1 cmp 并看到“逐字节比较两个文件......--verbose 输出字节数和不同的字节值”......我有一个偷偷摸摸的怀疑,只是从 python 调用 cmp 命令将是最优雅的解决方案。
  • cmp 还涵盖了所有边缘情况(例如一个文件比另一个文件大,等等)。

标签: python debugging hex diff instrumentation


【解决方案1】:

当 difflib 比较时,它会将每个 char 放入一个数组中,并在其前面加上一个 + 或 -。下面比较 x 和 y 然后我们看看输出:

   d = difflib.Differ()
   e = d.compare(x,y)        #set the compare output to a variable

   for i in range(0,len(e)):
       if i.startswith("-"):         #if that char start with "-" is not a match
           print(i + "index is different")

不匹配的字符将以“-”开头。 “+”表示它们是匹配的。

【讨论】:

    【解决方案2】:

    shell 命令cmp 已经完全符合我的需要/想要的。在 Python 中重新发明该功能将需要更多的努力/代码/时间......所以我只是从 Python 调用命令:

    #!/usr/bin/env python2
    import commands
    import numpy as np
    def run_cmp(filename1, filename2):
        cmd = 'cmp --verbose %s %s'%(filename1, filename2)
        status, output = commands.getstatusoutput(cmd) # python3 deprecated `commands` module FYI
        status = status if status < 255 else status%255
        if status > 1:
            raise RuntimeError('cmp returned with error (exitcode=%s, '
                    'cmd=\"%s\", output=\n\"%s\n\")'%(status, cmd, output))
        elif status == 1:
            is_different = True
        elif status == 0:
            is_different = False
        else:
            raise RuntimeError('invalid exitcode detected')
        return is_different, output
    if __name__ == '__main__':
        # create two binary files with different values
        # file 1
        tmp1 = np.arange(10, dtype=np.uint8)
        tmp1.tofile('tmp1')
        # file 2
        tmp2 = np.arange(10, dtype=np.uint8)
        tmp2[5] = 0xFF
        tmp2.tofile('tmp2')
        # compare using the shell command 'cmp'
        is_different, output = run_cmp(filename1='tmp1', filename2='tmp2')
        print 'is_different=%s, output=\n\"\n%s\n\"'%(is_different, output)
    

    【讨论】:

    • 在我的系统上,cmp 似乎只返回第一个不匹配的字节,我看不到任何联机帮助页选项来改变它。鉴于我正在尝试将一大堆尝试的 ROM 转储提炼成一个已损坏位的列表,这将取消它的资格。
    猜你喜欢
    • 2011-06-14
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2016-06-29
    • 2013-11-28
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多