Python中的差分二进制文件

Python中的差分二进制文件,python,diff,Python,Diff,我有两个二进制文件。它们看起来像这样,但数据更随机: 文件A: FF FF FF FF 00 00 00 00 FF FF 44 43 42 41 FF FF ... 文件B: 41 42 43 44 00 00 00 00 44 43 42 41 40 39 38 37 ... 我想称之为: >>> someDiffLib.diff(file_a_data, file_b_data) [Match(pos=4, length=4)] 并收到类似于: >>&

我有两个二进制文件。它们看起来像这样,但数据更随机:

文件A:

FF FF FF FF 00 00 00 00 FF FF 44 43 42 41 FF FF ...
文件B:

41 42 43 44 00 00 00 00 44 43 42 41 40 39 38 37 ...
我想称之为:

>>> someDiffLib.diff(file_a_data, file_b_data)
[Match(pos=4, length=4)]
并收到类似于:

>>> someDiffLib.diff(file_a_data, file_b_data)
[Match(pos=4, length=4)]
指示在两个文件中,位置4处的字节对于4个字节是相同的。序列
44 43 42 41
不匹配,因为它们在每个文件中的位置不同

有没有一个图书馆可以帮我做这件事?或者我应该编写循环来进行比较吗?

您可以使用以下示例:

from itertools import groupby

# this just sets up some byte strings to use, Python 2.x version is below
# instead of this you would use f1 = open('some_file', 'rb').read()
f1 = bytes(int(b, 16) for b in 'FF FF FF FF 00 00 00 00 FF FF 44 43 42 41 FF FF'.split())
f2 = bytes(int(b, 16) for b in '41 42 43 44 00 00 00 00 44 43 42 41 40 39 38 37'.split())

matches = []
for k, g in groupby(range(min(len(f1), len(f2))), key=lambda i: f1[i] == f2[i]):
    if k:
        pos = next(g)
        length = len(list(g)) + 1
        matches.append((pos, length))
或者使用列表理解与上面相同的内容:

matches = [(next(g), len(list(g))+1)
           for k, g in groupby(range(min(len(f1), len(f2))), key=lambda i: f1[i] == f2[i])
               if k]
下面是使用Python 2.x时示例的设置:

f1 = ''.join(chr(int(b, 16)) for b in 'FF FF FF FF 00 00 00 00 FF FF 44 43 42 41 FF FF'.split())
f2 = ''.join(chr(int(b, 16)) for b in '41 42 43 44 00 00 00 00 44 43 42 41 40 39 38 37'.split())

提供的
itertools.groupby
工作正常,但速度相当慢

我使用
numpy
编写了一个非常简单的尝试,并在我碰巧拥有的一个16MB文件上与其他解决方案进行了对比测试,在我的机器上大约快了42倍。熟悉
numpy
的人可能会显著改善这一点

import numpy as np

def compare(path1, path2):
    x,y = np.fromfile(path1, np.int8), np.fromfile(path2, np.int8)
    length = min(x.size, y.size)
    x,y = x[:length], y[:length]

    z = np.where(x == y)[0]
    if(z.size == 0) : return z

    borders = np.append(np.insert(np.where(np.diff(z) != 1)[0] + 1, 0, 0), len(z))
    lengths = borders[1:] - borders[:-1]
    starts = z[borders[:-1]]
    return np.array([starts, lengths]).T

-google中“diff in python”的第一个结果可能是@Andrey的副本谢谢,我试过了,但似乎
get_matching_blocks()
没有检查每个文件中的字节是否在同一位置,只是检查每个文件中是否存在序列。否则,是的,这正是我想要的。所以你想得到一个列表,列出比赛开始的每个位置和比赛的长度,而你不关心文件中如果正确排列的话会匹配的部分?@KyleStrand是的,我想是的。虽然我不确定在这种情况下“正确排列”是什么意思。在上面的例子中,我不希望
44434241
匹配,因为它们位于不同的位置;如果这是你的意思,热。我很喜欢你在那里做的事。我希望得到这样一个漂亮的答案。