Как сравнить двоичные файлы, чтобы проверить, совпадают ли они?


186

Какой самый простой способ (используя графический инструмент или командную строку в Ubuntu Linux) узнать, являются ли два двоичных файла одинаковыми или нет (за исключением отметок времени)? Мне не нужно на самом деле извлечь разницу. Мне просто нужно знать, одинаковы они или нет.


5
Вопрос с просьбой показать , как они отличаются: superuser.com/questions/125376/...
Чиро Сантилли郝海东冠状病六四事件法轮功

2
Страница man для cmpспециально говорит, что это делает байтовое сравнение, так что это мой по умолчанию для 2 двоичных файлов. diffявляется построчным и даст вам тот же ответ Да / Нет, но, конечно, не тот же дамп в стандартный поток вывода. Если строки длинные, потому что, возможно, они не являются текстовыми файлами, я бы предпочел cmp. diffимеет преимущество в том, что вы можете указать сравнение каталогов и -rрекурсию для сравнения нескольких файлов в одной команде.
H2ONaCl

Ответы:


180

Стандартный Unix diffпокажет, являются ли файлы одинаковыми или нет:

[me@host ~]$ diff 1.bin 2.bin
Binary files 1.bin and 2.bin differ

Если команды не выводятся, это означает, что файлы не имеют различий.


5
У diff, похоже, проблемы с действительно большими файлами. Я получил diff: memory exhaustedпри сравнении двух файлов 13G.
Юнвэй Ву

1
Интересный выход. diffговорит вам, что они "двойные" мухи. Поскольку все файлы можно считать двоичными, это странное утверждение.
H2ONaCl

7
Вы можете сообщить об идентичных файлах с опцией: diff -s 1.bin 2.binили diff --report-identical-files 1.bin 2.binЭто показываетFiles 1.bin and 2.bin are identical
Том

1
Нет, он скажет, что они «отличаются», поэтому они не одинаковы
Йозеф Климук

1
У меня есть два исполняемых файла, я знаю, что они разные, потому что я скомпилировал и запустил их, но все приведенные здесь параметры diff и cmp оценивают их как идентичные. Зачем? !!!
миркастат

107

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


9
Для варианта использования ОП описывает IMHO cmpболее эффективно, чем diff. Так что я бы предпочел это.
Halloleo

5
У меня есть сценарий оболочки, который запускается:cmp $1 $2 && echo "identical" || echo "different"
Steveha

2
останавливается ли cmp, когда он нашел первое различие, и отображает его, или он проходит через конец файлов?
Соп

cmpимеет «тихий» режим: -s, --quiet, --silent- suppress all normal output. Я еще не тестировал, но думаю, что он остановится на первой разнице, если она будет.
Виктор Ярема

90

Я обнаружил, что я искал Visual Binary Diff , доступный на:

  • Ubuntu:

    sudo apt install vbindiff
    
  • Arch Linux:

    sudo pacman -S vbindiff
    
  • Mac OS X через MacPorts :

    port install vbindiff
    
  • Mac OS X через Homebrew:

    brew install vbindiff
    

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

2
Это было сказано несколько раз, но это отличная маленькая программа! (к тому же на доморощенном)
johncip

2
Это должен быть принятый ответ, так как это гораздо лучший метод, чем мягкий и бесполезный вывод команды canonical diff.
Героид Мерфи

1
Это лучший инструмент для бинарного сравнения.
Карла Камарго

17

Используйте sha1 для генерации контрольной суммы:

sha1 [FILENAME1]
sha1 [FILENAME2]

3
Если бы у вас была только контрольная сумма для одного из файлов, это было бы полезно, но если у вас есть оба файла на диске, это не нужно. diffи cmpоба скажут вам, если они отличаются без каких-либо дополнительных усилий.
Джоннип

1
Разве это не sha1sumвместо sha1?
кол-

2
sha1 в NetBSD, sha1sum в Linux
Скотт Преснелл,

2
Есть два файла, которые будут возвращать один и тот же результат, несмотря на различие: shattered.io
mik

2
У SHA1 уже есть одна публичная коллизия ( shattered.io ) и, возможно, какая-то непубличная. Одна коллизия может быть использована для генерации бесчисленных коллизионных файлов. Вместо этого используйте SHA2 для хэширования.
Михал Амброз

12

В итоге я использовал hexdump для преобразования двоичных файлов в шестнадцатеричное представление, а затем открыл их в meld / kompare / любом другом инструменте сравнения. В отличие от вас я был после различий в файлах.

hexdump tmp/Circle_24.png > tmp/hex1.txt
hexdump /tmp/Circle_24.png > tmp/hex2.txt

meld tmp/hex1.txt tmp/hex2.txt

1
Используйте, hexdump -v -e '/1 "%02x\n"'если вы хотите, чтобы diff и увидеть точно, какие байты были вставлены или удалены.
Уильям Энтрикен

Meld также работает с двоичными файлами, когда они не преобразуются в шестнадцатеричный формат. Он показывает шестнадцатеричные значения для вещей, которых нет в наборе символов, в противном случае нормальные символы, что полезно для двоичных файлов, которые также содержат некоторый текст ascii. Многие, по крайней мере, начинают с волшебной струны.
Феликс Домбек

7

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

md5 <filename1>
md5 <filename2>

Если оба MD5-хэша (вывод команды) одинаковы, то эти два файла не отличаются.


7
Можете ли вы объяснить свои отрицательные голоса, пожалуйста? SHA1 имеет 4 голоса против, и если OP считает, что есть вероятность, что два файла могут быть одинаковыми или похожими, шансы на столкновение незначительны и не заслуживают того, чтобы проголосовать за MD5 ниже, но за голосование SHA1, за исключением того, что вы слышали, что вы должны хешировать свои пароли с SHA1 вместо MD5 (это другая проблема).
Рикки

2
не уверен в причине, но чистый cmp будет более эффективен, чем вычисление любой хеш-функции файлов и сравнение их (по крайней мере, только для 2 файлов)
Павел Шчур

1
если два файла большого размера и находятся на одном и том же диске (не ssd), вариант md5 или sha * может быть быстрее, потому что диски могут читать два файла последовательно, что экономит много движений головы
Даниэль Алдер

7
Я понизил голосование, потому что вы опубликовали второстепенный вариант более раннего (плохого) решения, когда это должен был быть комментарий.
Джоннип

6

Используйте команду cmp. Обратитесь к Бинарным файлам и Принудительному Сравнению текста для получения дополнительной информации.

cmp -b file1 file2

1
-bне сравнивает файлы в "двоичном режиме". Это на самом деле «В GNU cmpвы также можете использовать опцию -bили, --print-bytesчтобы показать ASCII-представление этих байтов». Это именно то, что я нашел, используя URL к руководству, которое вы предоставили.
Виктор Ярема

Виктор Ярема, я не знаю, что вы подразумеваете под "бинарным режимом". cmpпо сути бинарное сравнение на мой взгляд. -bВариант просто печатает первые байты , который отличается.
H2ONaCl

4

Для поиска дефектов флэш-памяти мне пришлось написать этот скрипт, который показывает все блоки размером 1 КБ, которые содержат различия (не только первый, как это cmp -bделается)

#!/bin/sh

f1=testinput.dat
f2=testoutput.dat

size=$(stat -c%s $f1)
i=0
while [ $i -lt $size ]; do
  if ! r="`cmp -n 1024 -i $i -b $f1 $f2`"; then
    printf "%8x: %s\n" $i "$r"
  fi
  i=$(expr $i + 1024)
done

Вывод:

   2d400: testinput.dat testoutput.dat differ: byte 3, line 1 is 200 M-^@ 240 M- 
   2dc00: testinput.dat testoutput.dat differ: byte 8, line 1 is 327 M-W 127 W
   4d000: testinput.dat testoutput.dat differ: byte 37, line 1 is 270 M-8 260 M-0
   4d400: testinput.dat testoutput.dat differ: byte 19, line 1 is  46 &  44 $

Отказ от ответственности: я взломал сценарий за 5 минут. Он не поддерживает аргументы командной строки и не поддерживает пробелы в именах файлов.


Я получаю "r: not found" (используя GNU linux)
unseen_rider

@unseen_rider какая оболочка, какая строка? Пожалуйста, позвоните сценарию, использующему sh -xдля отладки
Даниэль Алдер

Это через вызов скрипта из терминала. Строка 9.
unseen_rider

@unseen_rider Я не могу тебе помочь таким образом. Сценарий в порядке. Пожалуйста, опубликуйте результаты отладки на pastebin.com . Вы можете увидеть здесь, что я имею в виду: pastebin.com/8trgyF4A . Кроме того, скажите, пожалуйста, результатreadlink -f $(which sh)
Даниэль Олдер

Последняя команда дает /bin/dash. В настоящее время создаю пасту на пастин.
unseen_rider

4

Diff со следующими параметрами выполнит двоичное сравнение, чтобы проверить, отличаются ли файлы вообще, и выдает, если файлы одинаковые:

diff -qs {file1} {file2}

Если вы сравниваете два файла с одинаковыми именами в разных каталогах, вы можете использовать эту форму вместо:

diff -qs {file1} --to-file={dir2}

OS X El Capitan


3

Попробуйте diff -s

Краткий ответ: беги diffс -sпереключателем.

Длинный ответ: читайте ниже.


Вот пример. Давайте начнем с создания двух файлов со случайным двоичным содержимым:

$ dd if=/dev/random bs=1k count=1 of=test1.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0100332 s, 102 kB/s

                                                                                  
$ dd if=/dev/random bs=1k count=1 of=test2.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0102889 s, 99,5 kB/s

Теперь давайте сделаем копию первого файла:

$ cp test1.bin copyoftest1.bin

Теперь test1.bin и test2.bin должны отличаться:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

... и test1.bin и copyoftest1.bin должны быть идентичны:

$ diff test1.bin copyoftest1.bin

Но ждать! Почему нет выхода?!?

Ответ: это по замыслу. Нет вывода одинаковых файлов.

Но есть разные коды ошибок:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

$ echo $?
1


$ diff test1.bin copyoftest1.bin

$ echo $?
0

К счастью, теперь вам не нужно проверять коды ошибок каждый раз, потому что вы можете просто использовать переключатель -s(или --report-identical-files), чтобы сделать diff более подробным:

$ diff -s test1.bin copyoftest1.bin
Files test1.bin and copyoftest1.bin are identical

2

Radiff2 - это инструмент, разработанный для сравнения двоичных файлов, аналогично тому, как обычный diff сравнивает текстовые файлы.

Попробуйте, radiff2который является частью radare2дизассемблера. Например, с помощью этой команды:

radiff2 -x file1.bin file2.bin

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


1

Мои любимые, использующие xxd hex-dumper из пакета vim:

1) используя vimdiff (часть vim)

#!/bin/bash
FILE1="$1"
FILE2="$2"
vimdiff <( xxd "$FILE1" ) <( xxd "$FILE2" )

2) используя diff

#!/bin/bash
FILE1=$1
FILE2=$2
diff -W 140 -y <( xxd $FILE1 ) <( xxd $FILE2 ) | colordiff | less -R -p '  \|  '

0
md5sum binary1 binary2

Если md5sum одинакова, двоичные файлы совпадают

Например

md5sum new*
89c60189c3fa7ab5c96ae121ec43bd4a  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt
root@TinyDistro:~# cat new*
aa55 aa55 0000 8010 7738
aa55 aa55 0000 8010 7738


root@TinyDistro:~# cat new*
aa55 aa55 000 8010 7738
aa55 aa55 0000 8010 7738
root@TinyDistro:~# md5sum new*
4a7f86919d4ac00c6206e11fca462c6f  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt

1
Не совсем. Только вероятность высока.
Савва

Какова вероятность неудачи?
Ashish

Тонкий, но хуже, чем при использовании какого-либо варианта diff, над которым нет причин предпочитать его.
Савва

Вы должны изменить хеш MD5 на SHA2, чтобы этот совет был практичным. Сегодня любой ноутбук может генерировать коллизии в MD5 и на основе этого единственного префикса коллизии (2 файла одинакового размера, одинакового префикса и одинакового MD5) генерировать бесконечное количество коллизирующих файлов (имеющих одинаковый префикс, другой блок коллизии, один и тот же суффикс)
Михал Амброз

-1

Существует относительно простой способ проверить, совпадают ли два двоичных файла.

Если вы используете файл ввода / вывода на языке программирования; Вы можете хранить каждый бит обоих двоичных файлов в своих собственных массивах.

На этом этапе проверка так же проста, как:

if(file1 != file2){
    //do this
}else{
    /do that
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.