Уведомления

Группа в Telegram: @pythonsu

#1 Май 14, 2017 15:05:14

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

В общем задача такая: открыть 2 бинарных файла и,если так можно вообще, циклом+ветвлением сравнить каждый 16-ичный коды и ,если они не равны, выводить в новый текстовый документ.
Ну к примеру ,открываю 2 файла в WinHex . В одном файле код F8 A1 F6 ,а в другом F5 A2 F6. Программка должна сравнить и как результат вывести F6.
Пытаюсь создать саму программку и пробно вывести значения кода,но выводит какую-то билеберду:

 f = open(r"1.png", "rb")
f.readline(2)
print (f.readline(2))

Даже так я не могу сделать то,что хочу - не знаю как. Т.е если в файле 1.png первые 2 символа кода F8, должно и вывести F8. Но выводит текст.
Далее циклом, перебирать код (а так как он из 2 символов,то ,как я понял ,перебирать 2 символа с шагом “1”) и выводить разницу
Раньше обращался с подобным вопросом, получил ответ в виде
 file1 = r"d:\\22.jpg"
file2 = r"d:\\11.jpg"
 
with open(file1, 'br') as of1, open(file2, 'br') as of2:
    l1 = of1.read()
    l2 = of2.read()
    
    f1_f2 = set(enumerate(l1)) - set(enumerate(l2))
    f2_f1 = set(enumerate(l2)) - set(enumerate(l1))
 
    for offset, char in sorted(f1_f2, key=lambda x: x[0]):
        print("offset: {}\tchar: {:X}".format(offset, char))
    
    print()
    
    for offset, char in sorted(f2_f1, key=lambda x: x[0]):
        print("offset: {}\tchar: {:X}".format(offset, char))


Но проблема в том,что эта программка,если находит различие, выводит все ,что следует после различия,даже если код дальше одинаков.
А мне нужно,чтобы выводило каждое различие

В общем, мне нужно,чтобы файлы сравнивались и в новый файл копировало только их различие,а не как в приведенном коде, весь код после различия

Офлайн

#2 Май 14, 2017 15:19:30

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

Еще можно открыть так:

 bytelist = bytearray()
with open('01.mp3','rb') as bytes:
    for byte in bytes:
       bytelist.extend(byte)
       
file=open('2.dat','wb')
file.write(bytelist)
file.close()
Но опять же, во-первых,не сохраняется именно 16-ичный код (который проверяется в WinHex например) , а во-вторых,я не знаю,что сделать дальше

Офлайн

#3 Май 14, 2017 15:34:11

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9999
Репутация: +  857  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

Geleosgeleos
В общем задача такая: открыть 2 бинарных файла и,если так можно вообще, циклом+ветвлением сравнить каждый 16-ичный коды и ,если они не равны, выводить в новый текстовый документ.
Geleosgeleos
Ну к примеру ,открываю 2 файла в WinHex . В одном файле код F8 A1 F6 ,а в другом F5 A2 F6. Программка должна сравнить и как результат вывести F6.
Две противоречащих друг другу фразы. В одной говорится одно, в другой - противоположное.

Geleosgeleos
Раньше обращался с подобным вопросом, получил ответ в виде
Который оказался неправильным, потому что ты так и не поставил точно задачу. А писать десять неправильных программ нет никакого желания, потому что ты потом скажешь “а они тоже чуть-чуть неправильные”. Если ты задачу неправильно поставил, то у тебя по ней получаются неправильные программы. Вот кто-то неопытный тебе написал что-то впустую, можно ему только посочувствовать.



Офлайн

#4 Май 14, 2017 16:28:43

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

py.user.next
Согласен,неправильно пример привел.
Открываем 2 файла в WinHex и видим разные 16-ичные коды. Мне надо ,чтобы программка сравнила эти коды ,и ту часть кода именно из 2 файла,которым они различаются вывела в новый.
Первый файл ,открытый в WinHex,имеет 16иный код C8 A1 D5 12 , другой - C7 A1 D5 13. Программа должна сравнить эти коды. Разницу, т.е С7 и 13 вывести в новый файл. Может быть такое,что будет 2 почти одинаковых кода (только к примеру во втором несколько “лишних” байтов - различие). Тогда в новый файл,как результат, должно сохраняться это различие.

Отредактировано Geleosgeleos (Май 14, 2017 16:32:37)

Офлайн

#5 Май 14, 2017 16:40:06

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

А если оба файла имеют совсем разные коды, в новый файл выводить весь код 2 файла

Офлайн

#6 Май 14, 2017 17:13:41

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9999
Репутация: +  857  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

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

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



Отредактировано py.user.next (Май 14, 2017 17:18:22)

Офлайн

#7 Май 14, 2017 18:09:17

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

py.user.next
Короче, надо сделать адресацию байтов в обоих файлах, потом сравнивать байты с одинаковыми адресами и неравные байты с их адресами выводить в файл. Если по адресу с различающимся байтом дальше идут также различающиеся байты, то все эти байты объединяются в цепочку байт с одним адресом.Поэтому то, что он тебе предложил, неправильно работает алгоритмически. Тебе надо читать оба файла побайтово. Когда во втором файле находится байт, отличный от байта в первом файле (на той же позиции), то нужно его (и его адрес) записать в файл вывода и перейти в состояние присоединения байтов к цепочке. Это важный момент, нельзя их накапливать где-либо в оперативной памяти, так как их могут быть мегабайты. Когда при таком переборе (записи цепочки различающихся байт в файл вывода) встречается одинаковый байт, то нужно вернуться в прежнее состояние и продолжать сравнивать байты так, как в самом начале они сравнивались. При нахождении различающегося байта начинается новая цепочка и пишется в файл вывода, пока не встретится одинаковый байт.
Т.е правильно нахимичить с предыдущим кодом не получится*? а где об этом можно вообще узнать? потому что я не знаю,как это сделать просто физически. Ну раз ты говоришь об адресации,то на ум приходит список. т.е 2 файла сделать списками?

Офлайн

#8 Май 14, 2017 18:16:42

Geleosgeleos
Зарегистрирован: 2017-05-04
Сообщения: 14
Репутация: +  0  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

или опять же взять множества и использовать .difference_update? тогда если так,то нужно что-то обратное этой функции взять,ибо мне нужно не совпадения а различия(

Отредактировано Geleosgeleos (Май 14, 2017 18:17:41)

Офлайн

#9 Май 15, 2017 01:20:07

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9999
Репутация: +  857  -
Профиль   Отправить e-mail  

Побайтовое сравнение 2 файлов

Geleosgeleos
Т.е правильно нахимичить с предыдущим кодом не получится*?
Он загружает всё содержимое в память, что уже неправильно. Ты так возьмёшь пару файлов на сотни мегабайт или гигабайт и весь комп повиснет, потому что начнёт свопить на диск оперативку.

Geleosgeleos
  
    l1 = of1.read()
    l2 = of2.read()
Вот эти строки загружают файлы в память целиком.

В идеале, там надо читать файлы блоками, а потом эти блоки сравнивать между собой побайтово и писать в результирующий файл всё что надо. Но для начала подойдёт и побайтовое чтение файлов, а не поблочное. Он же в своём коде загружает всё в память - это хреновый путь (он подумал, так удобнее, а в итоге написал то, что надо переписывать). То, что у тебя jpg-файлы (а они чаще всего небольшие) - это всё случайные условия; программа должна быть расчитана на любые файлы, а любые файлы уже могут быть и большими. Это же сравниватель байт, он должен сравнивать байты где угодно, в том числе и в видео-файлах и так далее.

Так что у тебя должен быть цикл, который читает байт с одного файла и с другого файла, потом эти два байта сравнивает и если они разные, то пишет отличающийся байт в результирующий файл. Но результирующий файл будет потом читать человек, значит должна быть адресация (чтобы читатель понимал, откуда байт взят). В качестве адресации подойдёт числовая позиция байта в файле, но обычно делают два числа - сегмент и смещение (они оба большие, поэтому много адресов в файле так задать можно). Для начала можешь использовать просто позицию из одного числа (тем более в питоне числа длинные, проблем не будет с этим). Поначалу можешь без цепочки байт всё сделать - просто для каждого байта пишется его позиция, даже если она совпадает с позицией предыдущего найденного байта. А потом уже можно сделать цепочки, где такие байты (с одинаковыми позициями) будут писаться с одной позицией и друг за другом просто - как цепочка в одной позиции.

Geleosgeleos
Пытаюсь создать саму программку и пробно вывести значения кода,но выводит какую-то билеберду:
Эта билиберда прямо в файле записана, так что что ты пытаешься вывести - непонятно. Чтобы выводить байты, нужно их преобразовывать в hex-представление, а это делается через .format().



Отредактировано py.user.next (Май 15, 2017 01:31:52)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version