Wie vergleiche ich binäre Dateien in Linux?

416084
bertieb

Ich muss zwei Binärdateien vergleichen und die Ausgabe in der Form erhalten:

<fileoffset-hex> <file1-byte-hex> <file2-byte-hex>

für jedes andere Byte. Also wenn file1.binist

 00 90 00 11 

in binärer Form und file2.binist

 00 91 00 10 

Ich möchte so etwas bekommen

 00000001 90 91 00000003 11 10 

Gibt es eine Möglichkeit, dies in Linux zu tun? Ich weiß über, cmp -laber es verwendet ein Dezimalsystem für Offsets und Oktal für Bytes, das ich vermeiden möchte.

260
you're basically looking for "binary diff". i can imagine some reeeally ugly commandline one-liner with `od`... quack quixote vor 14 Jahren 9
@ quack quixote: Was ist hässlich an einem Einzeiler? ;) Bobby vor 14 Jahren 2
xdelta.org funktioniert ziemlich gut. Vielleicht lohnt sich ein Blick darauf. thatjuan vor 10 Jahren 0
Weil Sie diese Frage nicht beantworten können (https://superuser.com/questions/125376/how-do-i-compare-binary-files-in-linux#comment1508593_983263) (da Sie kein Benutzer sind) Ich wähle, um zu schließen. Ein binärer Diff, wie er hier explizit angefordert wird, ist überhaupt nicht nützlich, und ich bin der Meinung, dass Sie etwas Nützliches wünschen. ** Wenn Sie ein Byte am Anfang der Datei einfügen, sollten alle Bytes als unterschiedlich markiert sein? ** Ohne das zu wissen, ist das einfach zu vage. Evan Carroll vor 5 Jahren 0
Ganz zu schweigen davon, dass dies ausdrücklich gegen die Regeln in mehreren Bereichen verstößt, es geht um ** "Programmierung und Softwareentwicklung" **, und Sie fragen nach einem Produkt oder einer Empfehlung und nicht nach der Verwendung eines bestimmten Produkts. Evan Carroll vor 5 Jahren 0
Auch mit der Methode zu [radare] (https://superuser.com/a/1373977/11116) aktualisiert, aber ich denke immer noch, dass diese Frage sowohl ein Thema als auch zu vage ist. Evan Carroll vor 5 Jahren 0
@EvanCarroll Wenn Sie der Meinung sind, dass die Frage kein Thema ist, warum beantworten Sie sie? DavidPostill vor 5 Jahren 1
@DavidPostill Ich glaube nicht, dass es nicht das Thema ist. Ich finde es eine großartige Frage. Ich denke, es ist schlecht formuliert und die Admins hier würden unangemessene Probleme verursachen, wenn ich es sonst versuchen würde, es zu retten. Weitere Informationen finden Sie in meiner Antwort. Binäre differ Frage? ** JA! ** Byte für Byteunterschied? Nun, das macht in keinem Fall Sinn, den ich mir vorstellen kann. Evan Carroll vor 5 Jahren 0

14 Antworten auf die Frage

149
Dennis Williamson

Dadurch werden Offset und Bytes in Hex gedruckt:

cmp -l file1.bin file2.bin | gawk '' 

Oder machen Sie $1-1den ersten gedruckten Offset bei 0.

cmp -l file1.bin file2.bin | gawk '' 

Leider strtonum()ist dies spezifisch für GAWK, daher müssen Sie für andere Versionen von awk - z. B. mawk - eine Oktal-Dezimal-Konvertierungsfunktion verwenden. Zum Beispiel,

cmp -l file1.bin file2.bin | mawk 'function oct2dec(oct, dec) ; return dec} ' 

Zur besseren Lesbarkeit ausgebrochen:

cmp -l file1.bin file2.bin | mawk 'function oct2dec(oct, dec) { for (i = 1; i <= length(oct); i++) { dec *= 8; dec += substr(oct, i, 1) }; return dec } { printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3) }' 
@gertvdijk: `strtonum` ist spezifisch für GAWK. Ich glaube, Ubuntu hat früher GAWK als Standard verwendet, aber irgendwann auf "mawk" umgestellt. In jedem Fall kann GAWK installiert und auf den Standard gesetzt werden (siehe auch "man Update-Alternativen"). In meiner aktualisierten Antwort finden Sie eine Lösung, die kein Strtonum erfordert. Dennis Williamson vor 10 Jahren 3
144
akira

Wie ~ quack darauf hinwies:

 % xxd b1 > b1.hex % xxd b2 > b2.hex 

Und dann

 % diff b1.hex b2.hex 

oder

 % vimdiff b1.hex b2.hex 
In Bash: `diff <(xxd b1) <(xxd b2)` but the output format of this (or yours) is nowhere near what op asked for. < />iv> Dennis Williamson vor 14 Jahren 61
Bei vimdiff werden die Bytes in den Zeilen dargestellt, in denen sich die beiden Dateien unterscheiden akira vor 14 Jahren 6
Aww, warum habe ich nicht daran gedacht? Und ich bin mir sicher, dass ich diese Technik auch in der Vergangenheit angewendet habe. njd vor 14 Jahren 0
Nett. Ich bin auf einem eingebetteten System, das BusyBox verwendet, und es gibt kein "cmp", aber "hexdump" + "diff" wirkt wie ein Zauber. Robert Calhoun vor 11 Jahren 0
Das funktionierte für mich großartig (mit "opendiff" unter OS X anstelle von "vimdiff"). Die Standardansicht "xxd" sorgt dafür, dass die Diff-Engine Byte für Byte im Vergleich bleibt. Mit einfachen (rohen) Sechskantfeldern, die einfach säulenförmig mit "fold" passen, versucht "diff", zufälliges Material in den Dateien, die ich verglichen habe, zu falten / gruppieren. natevw vor 9 Jahren 1
Dieser Befehl funktioniert nicht gut für das Entfernen von Bytes, da jede folgende Zeile falsch ausgerichtet ist und als von "diff" geändert betrachtet wird. Die Lösung besteht darin, 1 Byte pro Zeile zu setzen und die Adressspalte zu entfernen, wie von [John Lawrence Aspden] (http://superuser.com/a/332939/128124) und [me] (http://superuser.com/) vorgeschlagen. a / 897902/128124). Ciro Santilli 新疆改造中心 六四事件 法轮功 vor 9 Jahren 1
66
kenorb

Versuchen Sie es diffmit der folgenden Kombination von zsh / bash-Prozessersetzung und colordiffin CLI:

diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff 

Woher:

  • -y zeigt Ihnen die Unterschiede nebeneinander (optional)
  • xxd ist ein CLI-Tool zum Erstellen einer Hexdump-Ausgabe der Binärdatei
  • colordiffkolorieren wird diffausgegeben (installieren über: sudo apt-get install colordiff)
  • hinzufügen, -W200um difffür eine breiteren Ausgang

Hinweise:

  • Wenn die Dateien zu groß sind, fügen Sie -l1000für jede Datei ein Limit hinzuxxd

Beispielausgabe:

binary file output in terminal - diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff

Der Befehl kann vereinfacht werden als `colordiff -y <(xxd foo1.bin) <(xxd foo2.bin)`. golem vor 8 Jahren 7
Wenn Sie keinen colordiff haben, wird dies auch ohne Farben funktionieren: `diff -y <(xxd foo1.bin) <(xxd foo2.bin)` Rock Lee vor 7 Jahren 3
Wenn Sie nur wissen möchten, ob beide Dateien tatsächlich gleich sind, können Sie den Schalter "-q" oder "--brief" verwenden, der die Ausgabe nur anzeigt, wenn sich die Dateien unterscheiden. Stefan van den Akker vor 7 Jahren 4
Erstellen Sie dazu eine Funktion `xxddiff` mit:` xxddiff () (f () (xxd "$ 1";); diff -y <(f "$ 1") <(f "$ 2") | colordiff;) ` rubo77 vor 7 Jahren 1
großartig! noch: `diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim -` wird einen guten Job machen ribamar vor 5 Jahren 1
48
njd

Es gibt ein Tool namens DHEX, das die Arbeit erledigen kann, und es gibt ein anderes Tool namens VBinDiff .

Versuchen Sie es mit einem strengen Befehlszeilenansatz mit JDIFF .

DHEX ist fantastisch, wenn Sie Binärdateien vergleichen möchten. Füttern Sie zwei Dateien, und Sie gelangen direkt zu einer vergleichenden Ansicht, wobei Unterschiede hervorgehoben werden, und Sie können problemlos zum nächsten Unterschied wechseln. Es ist auch in der Lage, mit großen Terminals zu arbeiten, was auf Breitbildmonitoren sehr nützlich ist. Marcin vor 12 Jahren 8
Ich bevorzuge VBinDiff. DHEX verwendet CPU auch im Leerlauf. Ich denke, es wird ständig neu gezeichnet. VBinDiff funktioniert jedoch nicht mit breiten Terminals. Bei breiten Terminals werden die Adressen trotzdem unheimlich, da Sie pro Zeile mehr als 16 Bytes haben. Janus Troelsen vor 11 Jahren 6
vbindiff lässt uns die Datei tatsächlich bearbeiten, thx! Aquarius Power vor 9 Jahren 0
+1 Aber warum sagen sie in jdiff -h: "Verwenden Sie jdiff nicht direkt für komprimierte Dateien wie zip, gzip, rar, ..."? 1111161171159459134 vor 8 Jahren 0
@DanielBeauyat-komprimierte Dateien unterscheiden sich nach dem ersten unterschiedlichen Byte vollständig. Die Ausgabe ist wahrscheinlich nicht nützlich. Mark Ransom vor 8 Jahren 2
@ 1111161171159459134 jdiff ist Teil einer "Suite" von Programmen zum Synchronisieren und Korrigieren der von jdiff gefundenen Unterschiede. Aber, wie Mark Ransom sagte, wäre das bei komprimierten Dateien generell nicht sinnvoll; Die Ausnahme sind "synchronisierbare" komprimierte Formate (wie die von gzip --rsyncable erzeugten), bei denen kleine Unterschiede in den unkomprimierten Dateien eine begrenzte Auswirkung auf die komprimierte Datei haben sollten. hmijail vor 8 Jahren 2
Ich war glücklich, "vbindiff" in den Debian-Repos zu finden. Jonathon Reinhart vor 6 Jahren 0
`vbindiff` kann kein Byte hinzufügen / löschen, nur vorhandenes Byte bearbeiten. 林果皞 vor 5 Jahren 0
25
Ciro Santilli 新疆改造中心 六四事件 法轮功

Methode, die für das Hinzufügen / Löschen von Bytes funktioniert

diff <(od -An -tx1 -w1 -v file1) \ <(od -An -tx1 -w1 -v file2) 

Generieren Sie einen Testfall mit einmaligem Entfernen von Byte 64:

for i in `seq 128`; do printf "%02x" "$i"; done | xxd -r -p > file1 for i in `seq 128`; do if [ "$i" -ne 64 ]; then printf "%02x" $i; fi; done | xxd -r -p > file2 

Ausgabe:

64d63 < 40 

Wenn Sie auch die ASCII-Version des Zeichens sehen möchten:

bdiff() ( f() ( od -An -tx1c -w1 -v "$1" | paste -d '' - - ) diff <(f "$1") <(f "$2") )  bdiff file1 file2 

Ausgabe:

64d63 < 40 @ 

Getestet auf Ubuntu 16.04.

Ich ziehe es odüber, xxdweil:

  • es POSIX ist, xxdist nicht (kommt mit Vim)
  • hat das -An, um die Adressspalte ohne zu entfernen awk.

Befehlserklärung:

  • -AnEntfernt die Adressspalte. Dies ist wichtig, da sich ansonsten alle Zeilen nach dem Hinzufügen / Entfernen eines Bytes unterscheiden.
  • -w1setzt ein Byte pro Zeile, damit diff es verbrauchen kann. Es ist entscheidend, ein Byte pro Zeile zu haben, sonst würde jede Zeile nach einer Löschung außer Phase geraten und unterschiedlich sein. Leider ist dies nicht POSIX, sondern in GNU vorhanden.
  • -tx1 Ist die gewünschte Darstellung, ändern Sie die Werte in einen beliebigen Wert, solange Sie 1 Byte pro Zeile behalten.
  • -vVerhindert die Abkürzung für *die Wiederholung von Sternen, die den Unterschied stören könnte
  • paste -d '' - -verbindet alle zwei Zeilen. Wir brauchen es, weil das Hex und das ASCII in getrennten nebeneinander liegenden Zeilen stehen. Entnommen aus: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • wir verwenden Klammer ()zu definieren, bdiffanstatt {}den Umfang der inneren Funktion zu begrenzen f, siehe auch: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

Siehe auch:

13
Evgeny

Kurze Antwort

vimdiff <(xxd -c1 -p first.bin) <(xxd -c1 -p second.bin) 

Insbesondere beim Verwenden von Hexdumps und Textdifferenzen zum Vergleichen von Binärdateien ändern sich xxdbeim Hinzufügen und Entfernen von Bytes Verschiebungen bei der Adressierung, was die Anzeige möglicherweise erschwert. Diese Methode weist xxd an, keine Adressen auszugeben und nur ein Byte pro Zeile auszugeben, was wiederum genau angibt, welche Bytes geändert, hinzugefügt oder entfernt wurden. Sie können die Adressen später finden, indem Sie in einem "normalen" Hexdump (Ausgabe von xxd first.bin) nach interessanten Bytefolgen suchen .

(Natürlich kann man statt 'vimdiff' auch 'diff' verwenden.) VasyaNovikov vor 8 Jahren 0
11
BugoK

Ich würde hexdump empfehlen, um Binärdateien in ein Textformat zu speichern, und kdiff3 für die Diff-Anzeige.

hexdump myfile1.bin > myfile1.hex hexdump myfile2.bin > myfile2.hex kdiff3 myfile1.hex myfile2.hex 
Auch hier in bash `kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin)` ohne dass die Dateien `myfile1.hex` und` myfile2.hex` erstellt werden müssen. Hastur vor 8 Jahren 2
4
Mick

Das hexdiffist ein Programm, das genau das macht, wonach Sie suchen.

Verwendungszweck:

hexdiff file1 file2 

Es zeigt den Hexadezimalcode (und den 7-Bit-ASCII-Code) der beiden Dateien übereinander an, wobei alle Unterschiede hervorgehoben werden. Suchen Sie man hexdiffnach den Befehlen, um sich in der Datei zu bewegen, und eine einfache qwird beendet.

Aber es macht einen ziemlich schlechten Job, wenn es um den Vergleichsteil geht. Wenn Sie einige Bytes in eine Datei einfügen, werden alle Bytes danach als Änderungen markiert Murmel vor 7 Jahren 4
und hexdiff ist nicht über apt-get unter Ubuntu 16.4 verfügbar rubo77 vor 7 Jahren 0
@ Murmel, obwohl ich einverstanden bin, wird hier nicht gefragt? Evan Carroll vor 5 Jahren 0
@EvanCarroll wahr, und deshalb habe ich einen Kommentar hinterlassen (nur) und habe nicht abgelehnt Murmel vor 5 Jahren 0
Ich habe Mick auch nicht abgelehnt, aber ich stimme mit Ihnen überein und antwortete hier https://superuser.com/a/1373977/11116, da es wahrscheinlich ist, dass diese schlechte Frage reformiert oder geschlossen wird. Evan Carroll vor 5 Jahren 0
3
John Lawrence Aspden

Es kann die Frage nicht streng beantworten, aber ich verwende das für die Differenzierung von Binärdateien:

gvim -d <(xxd -c 1 ~/file1.bin | awk '') <(xxd -c 1 ~/file2.bin | awk '') 

Beide Dateien werden als Hexadezimal- und ASCII- Werte (ein Byte pro Zeile) gedruckt und dann mit der Diff-Funktion von Vim visuell dargestellt.

0
Vincent Vega

dhex http://www.dettus.net/dhex/

DHEX is a more than just another hex editor: It includes a diff mode, which can be used to easily and conveniently compare two binary files. Since it is based on ncurses and is themeable, it can run on any number of systems and scenarios. With its utilization of search logs, it is possible to track changes in different iterations of files easily.

Willkommen bei SuperUser! Obwohl diese Software so aussieht, als könnte sie das Problem des OP lösen, ist reine Werbung im Stack Exchange-Netzwerk sehr verpönt. Wenn Sie mit dem Editor dieser Software verbunden sind, geben Sie diese Tatsache bitte an. Versuchen Sie, Ihren Post so zu schreiben, dass er weniger wie ein Werbespot aussieht. Vielen Dank. Nathan.Eilisha Shiraini vor 6 Jahren 0
Ich bin in keiner Weise mit dhex verbunden. Ich habe die Beschreibung des Autors in den Beitrag kopiert, da es eine Mindestlänge für die Beitragslänge gibt Vincent Vega vor 6 Jahren 0
Bereits erwähnt unter: https://superuser.com/a/125390/128124 Ciro Santilli 新疆改造中心 六四事件 法轮功 vor 6 Jahren 0