Должен ли я сравнивать байты, используя struct? - PullRequest
3 голосов
/ 14 августа 2010

Я пытаюсь сравнить данные в двух файлах и получить список смещений различий.Я попробовал это на некоторых текстовых файлах, и это работало довольно хорошо. Однако на нетекстовых файлах (которые все еще содержат текст ascii), я называю их файлами двоичных данных.(исполняемые файлы и т. д.)

Кажется, что некоторые байты одинаковы, хотя, когда я смотрю на это в шестнадцатеричном редакторе, они явно не совпадают.Я попытался распечатать эти двоичные данные, которые они считают одинаковыми, и я получил пустые строки, где они должны быть напечатаны.Таким образом, я думаю, что это источник проблемы.

Итак, каков наилучший способ сравнения байтов данных, которые могут быть как двоичными, так и содержать текст ascii?Я думал, что использование модуля struct будет отправной точкой ...

Как вы можете видеть ниже, я сравниваю байты с оператором ==

Вот код:

import os
import math


#file1 = 'file1.txt'
#file2 = 'file2.txt'
file1 = 'file1.exe'
file2 = 'file2.exe'
file1size = os.path.getsize(file1)
file2size = os.path.getsize(file2)
a = file1size - file2size
end = file1size  #if they are both same size
if a > 0:
    #file 2 is smallest
    end = file2size
    big = file1size

elif a < 0:
    #file 1 is smallest
    end = file1size
    big = file2size


f1 = open(file1, 'rb')
f2 = open(file2, 'rb')



readSize = 500
r = readSize
off = 0
data = []
looking = False
d = open('data.txt', 'w')


while off < end:
    f1.seek(off)
    f2.seek(off)
    b1, b2 = f1.read(r), f2.read(r)
    same = b1 == b2
    print ''
    if same:
        print 'Same at: '+str(off)
        print 'readSize: '+str(r)
        print b1
        print b2
        print ''
        #save offsets of the section of "different" bytes
        #data.append([diffOff, diffOff+off-1])  #[begin diff off, end diff off]
        if looking:
            d.write(str(diffOff)+" => "+str(diffOff+off-2)+"\n")
            looking = False
            r = readSize
            off = off + 1
        else:
            off = off + r

    else:
        if r == 1:
            looking = True
            diffOff = off
            off = off + 1 #continue reading 1 at a time, until u find a same reading
        r = 1  #it will shoot back to the last off, since we didn't increment it here



d.close()
f1.close()
f2.close()          

#add the diff ending portion to diff data offs, if 1 file is longer than the other
a = int(math.fabs(a))  #get abs val of diff
if a:
    data.append([big-a, big-1])


print data

Ответы [ 2 ]

4 голосов
/ 14 августа 2010

Вы пробовали difflib и filecmp модули?

Этот модуль предоставляет классы и функции для сравнения последовательностей. Это может быть использован, например, для сравнения файлы, и может дать разницу информация в различных форматах, в том числе HTML и контекст и унифицированные дифференциалы. Для сравнения каталогов и файлы, см. также модуль filecmp.

Модуль filecmp определяет функции сравнивать файлы и каталоги, с различные дополнительные время / правильность компромиссные. Для сравнения файлов смотрите также модуль difflib

.

0 голосов
/ 15 августа 2010

Возможно, вы столкнулись с проблемами кодирования / декодирования. Кто-то может предложить лучшее решение, но вы можете попробовать прочитать файл в bytearray, чтобы вы читали необработанные байты вместо декодированных символов:

Вот пример:

$ od -Ax -tx1 /tmp/aa
000000 e0 b2 aa 0a
$ od -Ax -tx1 /tmp/bb
000000 e0 b2 bb 0a

$ cat /tmp/diff.py 
a = bytearray(open('/tmp/aa', 'rb').read())
b = bytearray(open('/tmp/bb', 'rb').read())
print "%02x, %02x" % (a[2], a[3])
print "%02x, %02x" % (b[2], b[3])

$ python /tmp/diff.py 
aa, 0a
bb, 0a
...