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


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.