Je dois comparer deux fichiers binaires et obtenir le résultat sous la forme:
<fileoffset-hex> <fichier1 octets-hex> <fichier2 octets-hex>
pour chaque octet différent. Donc, si file1.bin
est
00 90 00 11
sous forme binaire et file2.bin
est
00 91 00 10
Je veux obtenir quelque chose comme
00000001 90 91
00000003 11 10
Y a-t-il un moyen de faire cela sous Linux? Je connais cmp -l
, mais il utilise un système décimal pour les décalages et octal pour les octets, ce que je voudrais éviter.
Ceci imprimera le décalage et les octets au format hexadécimal:
cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'
Ou bien faites $1-1
pour que le premier offset imprimé commence à 0.
cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1-1, strtonum(0$2), strtonum(0$3)}'
Malheureusement, strtonum()
étant spécifique à GAWK, vous devrez utiliser une fonction de conversion octale à décimale pour les autres versions de awk, par exemple mawk. Par exemple,
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)}'
Éclaté pour plus de lisibilité:
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)
}'
Comme ~ charlatan fit remarquer:
% xxd b1 > b1.hex
% xxd b2 > b2.hex
Et alors
% diff b1.hex b2.hex
ou
% vimdiff b1.hex b2.hex
diff
+ xxd
Essayez diff
dans la combinaison suivante de substitution de processus zsh/bash et colordiff
dans l'interface de ligne de commande:
diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff
Où:
-y
affiche les différences côte à côte (facultatif)xxd
est un outil CLI permettant de créer une sortie hexdump du fichier binaire-W200
à diff
pour une sortie plus large (de 200 caractères par ligne)colordiff
+ xxd
Si vous avez colordiff
, il peut coloriser la sortie diff
, par exemple:
colordiff -y <(xxd foo1.bin) <(xxd foo2.bin)
Sinon, installez via: Sudo apt-get install colordiff
.
Exemple de sortie:
vimdiff
+ xxd
Vous pouvez également utiliser vimdiff
, par exemple.
vimdiff <(xxd foo1.bin) <(xxd foo2.bin)
Astuces:
-l1000
) pour chaque xxd
Méthode qui fonctionne pour l'ajout/la suppression d'octets
diff <(od -An -tx1 -w1 -v file1) \
<(od -An -tx1 -w1 -v file2)
Générez un scénario de test avec une seule suppression de l'octet 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
Sortie:
64d63
< 40
Si vous souhaitez également voir la version ASCII du caractère:
bdiff() (
f() (
od -An -tx1c -w1 -v "$1" | paste -d '' - -
)
diff <(f "$1") <(f "$2")
)
bdiff file1 file2
Sortie:
64d63
< 40 @
Testé sur Ubuntu 16.04.
Je préfère od
à xxd
parce que:
xxd
n'est pas (livré avec Vim)-An
pour supprimer la colonne d'adresse sans awk
.Explication de la commande:
-An
supprime la colonne d'adresse. C'est important sinon toutes les lignes seraient différentes après l'ajout/le retrait d'un octet.-w1
met un octet par ligne, pour que diff puisse le consommer. Il est crucial d’avoir un octet par ligne, sinon chaque ligne après une suppression deviendrait déphasée et différerait. Malheureusement, ce n'est pas POSIX, mais présent dans GNU.-tx1
est la représentation souhaitée, remplacez-la par une valeur possible, à condition de conserver un octet par ligne.-v
empêche l'abréviation de répétition astérisque *
qui pourrait interférer avec le diffpaste -d '' - -
rejoint toutes les deux lignes. Nous en avons besoin car l'hex et ASCII vont dans des lignes adjacentes séparées. Extrait de: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next()
pour définir bdiff
au lieu de {}
pour limiter la portée de la fonction interne f
, voir aussi: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another -function-in-bashVoir également:
Réponse courte
vimdiff <(xxd -c1 -p first.bin) <(xxd -c1 -p second.bin)
Lorsque vous utilisez hexdumps et text diff pour comparer des fichiers binaires, en particulier xxd
, les ajouts et suppressions d'octets deviennent des modifications dans l'adressage, ce qui peut rendre la lecture difficile. Cette méthode indique à xxd de ne pas afficher les adresses et de ne générer qu'un seul octet par ligne, ce qui indique à son tour quels octets ont été modifiés, ajoutés ou supprimés. Vous pourrez trouver les adresses plus tard en recherchant les séquences d'octets intéressantes dans un hexdump plus "normal" (sortie de xxd first.bin
).
Je recommanderais hexdump pour vider les fichiers binaires au format texte et kdiff3 pour les diff.
hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex
La hexdiff
est un programme conçu pour faire exactement ce que vous recherchez.
Usage:
hexdiff file1 file2
Il affiche le format hexadécimal (et ASCII 7 bits) des deux fichiers superposés, avec les différences mises en évidence. Regardez man hexdiff
pour les commandes à déplacer dans le fichier, et un simple q
quittera.
Cela ne répond peut-être pas strictement à la question, mais je l'utilise pour les fichiers binaires différents:
gvim -d <(xxd -c 1 ~/file1.bin | awk '{print $2, $3}') <(xxd -c 1 ~/file2.bin | awk '{print $2, $3}')
Il imprime les deux fichiers sous forme de valeurs hexadécimales et ASCII , un octet par ligne, puis utilise la fonction de diff de Vim pour les rendre visuellement.
dhex http://www.dettus.net/dhex/
DHEX est un autre éditeur hexadécimal: il comprend un mode diff, qui permet de comparer facilement et commodément deux fichiers binaires. Comme il est basé sur ncurses et qu'il est possible de les utiliser, il peut être exécuté sur un nombre quelconque de systèmes et de scénarios. Avec son utilisation des journaux de recherche, il est possible de suivre facilement les modifications apportées à différentes itérations de fichiers.
Vous pouvez utiliser gvimdiff outil inclus dans vim-gui-common package
Sudo apt-get update
Sudo apt-get installer vim-gui-common
Ensuite, vous pouvez comparer 2 fichiers hexadécimaux en utilisant les commandes suivantes:
ubuntu> gvimdiff <hex-file1> <hex-file2>
C'est tout. J'espère que l'aide!