Як порівняти двійкові файли, щоб перевірити, чи вони однакові?


186

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


5
Питання з проханням показати , як вони відрізняються: superuser.com/questions/125376 / ...
— Чіро Сантіллі郝海东冠状病六四事件法轮功

2
Сторінка man для cmpконкретно говорить, що вона робить байт за байтом порівняння, так що моє значення за замовчуванням для двох бінарних файлів. 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.
— Yongwei Wu

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, наведені тут, вважають їх однаковими. Чому? !!!
— mirkastath

107

Використовувати cmpкоманду. Це або вийде чисто, якщо вони є двійковими рівними, або він роздрукує, де виникає перша різниця та вийде.


9
У випадку використання ОП описує, що ІМХО cmpє більш ефективним, ніж diff. Тому я вважаю за краще це.
— halloleo

5
У мене є сценарій оболонки, який працює:cmp $1 $2 && echo "identical" || echo "different"
— steveha

2
чи зупиняється cmp, коли він знайшов першу різницю, і відображає її чи проходить через кінець файлів?
— соп

cmpмає режим "безшумний": -s, --quiet, --silent- suppress all normal output. Я ще не тестував, але думаю, що він зупиниться при першій різниці, якщо є.
— Віктор Ярема

89

Я знайшов 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
Про це говорилося кілька разів, але це чудова маленька програма! (fyi також по-домашньому)
— johncip

2
Це має бути прийнятою відповіддю, оскільки це набагато вищий метод, ніж спритний і недоброзичливий вихід канонічної команди diff.
— Gearoid Murphy

1
Це найкращий інструмент для двійкових розл.
— Карла Камарго

17

Використовуйте sha1 для створення контрольної суми:

sha1 [FILENAME1]
sha1 [FILENAME2]

3
Якщо у вас була лише контрольна сума для одного з файлів, це буде корисно, але якщо у вас обидва файли на диску, це зайве. diffі cmpвони вам скажуть, чи відрізняються вони без зайвих зусиль.
— johncip

1
Чи не sha1sumзамість цього sha1?
— кол

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

2
Є два файли, які повернуть той самий результат, незважаючи на те, що вони різні: shattered.io
— mik

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

12

Я в кінцевому підсумку використовував hexdump для перетворення бінарних файлів у шістнадцяткове представлення, а потім відкрив їх у meld / kompare / будь-якому іншому інструменті diff. На відміну від вас, я був після відмінностей у файлах.

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"'якщо ви хочете відрізнятись і бачити, які саме байти було вставлено чи видалено.
— Вільям Ентрікен

Meld також працює з бінарними файлами, коли вони спочатку не перетворюються на шістнадцятковий. Він показує шістнадцяткові значення для речей, які відсутні в наборі char, в іншому випадку звичайні символи, що корисно для бінарних файлів, які також містять деякий текст ascii. Багато хто робить, принаймні починаючи з чарівної струни.
— Фелікс Домбек

7

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

md5 <filename1>
md5 <filename2>

Якщо обидва хеші MD5 (вихід команди) однакові, два файли не відрізняються.


7
Чи можете ви пояснити свої голоси? У SHA1 є 4 відгуки, і якщо ОП вважає, що шанс двох файлів може бути однаковим чи подібним, шанси на зіткнення невеликі і не варті того, щоб голосувати за MD5, але голосувати за SHA1, окрім того, що ви чули, що ви повинні хеш паролі з SHA1 замість MD5 (це інша проблема).
— Рікі

2
не впевнений у причині, але чистий cmp буде більш ефективним, ніж обчислення будь-яких хеш-функцій файлів та їх порівняння (принаймні, лише для двох файлів)
— Paweł Szczur,

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

7
Я заявив, що ви опублікували незначний варіант попереднього (поганого) рішення, коли він мав бути коментарем.
— johncip

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: не знайдено" (за допомогою 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 -qs {file1} {file2}

Якщо ви порівнюєте два файли з однаковою назвою в різних каталогах, можете замість цього скористатися цією формою:

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

OS X El Capitan


3

Спробуйте розріз

Коротка відповідь: запустіть 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) використовуючи розл

#!/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
Не зовсім. Лише можливість висока.
— sawa

Яка ймовірність невдачі?
— Ashish

Тонкий, але гірший, ніж використання якогось варіанту diff, над яким немає причин віддавати перевагу.
— sawa

Вам слід змінити хеш 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.