How do I compare binary files in Linux?
This video is brought to you by Memorabit, an app that sends technical terms, commands and definitions as reminders at unexpected moments, so they stay in memory. Built on cognitive science principles. Start free on web, iOS and Android:
iOS: https://apps.apple.com/app/id6782301691
Android: https://play.google.com/store/apps/detai...
--------------------------------------------------
Read the revolutionary AI books written by Turbina Editore, the first publishing house entirely run by artificial intelligence. This groundbreaking publisher has transformed the literary world, producing the most sought-after AI-generated books. Start reading today at:
https://turbinaeditore.com/en/
--------------------------------------------------
--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Take control of your privacy with Proton's trusted, Swiss-based, secure services.
Choose what you need and safeguard your digital life:
Mail: https://go.getproton.me/SH1CU
VPN: https://go.getproton.me/SH1DI
Password Manager: https://go.getproton.me/SH1DJ
Drive: https://go.getproton.me/SH1CT
Music by Eric Matyas
https://www.soundimage.org
Track title: Quirky Dreamscape Looping
--
Chapters
00:00 How Do I Compare Binary Files In Linux?
00:35 Answer 1 Score 83
00:49 Answer 2 Score 288
01:04 Accepted Answer Score 269
01:52 Answer 4 Score 52
03:47 Thank you
--
Full question
https://superuser.com/questions/125376/h...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#linux #diff #binaryfiles
#avk47
ANSWER 1
Score 288
As ~quack pointed out:
% xxd b1 > b1.hex
% xxd b2 > b2.hex
And then
% diff b1.hex b2.hex
or
% vimdiff b1.hex b2.hex
ACCEPTED ANSWER
Score 269
This will print the offset and bytes in hex:
cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'
Or do $1-1 to have the first printed offset start at 0.
cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1-1, strtonum(0$2), strtonum(0$3)}'
Unfortunately, strtonum() is specific to GAWK, so for other versions of awk—e.g., mawk—you will need to use an octal-to-decimal conversion function. For example,
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)}'
Broken out for readability:
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)
}'
ANSWER 3
Score 83
There's a tool called DHEX which may do the job, and there's another tool called VBinDiff.
For a strictly command-line approach, try jojodiff.
ANSWER 4
Score 52
diff + od method that works for byte addition / deletion
diff <(od -An -tx1 -w1 -v file1) \
<(od -An -tx1 -w1 -v file2)
which you may want to alias in Bash as:
bdiff() {
diff <(od -An -tx1 -w1 -v "$1") \
<(od -An -tx1 -w1 -v "$2")
}
Generate a test case with a single removal of 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
Output:
64d63
< 40
If you also want to see the ASCII version of the character:
bdiff() (
f() (
od -An -tx1c -w1 -v "$1" | paste -d '' - -
)
diff <(f "$1") <(f "$2")
)
bdiff file1 file2
Output:
64d63
< 40 @
Tested on Ubuntu 16.04.
I prefer od over xxd because:
- it is POSIX,
xxdis not (comes with Vim) - has the
-Anto remove the address column withoutawk.
Command explanation:
-Anremoves the address column. This is important otherwise all lines would differ after a byte addition / removal.-w1puts one byte per line, so that diff can consume it. It is crucial to have one byte per line, or else every line after a deletion would become out of phase and differ. Unfortunately, this is not POSIX, but present in GNU.-tx1is the representation you want, change to any possible value, as long as you keep 1 byte per line.-vprevents asterisk repetition abbreviation*which might interfere with the diffpaste -d '' - -joins every two lines. We need it because the hex and ASCII go into separate adjacent lines. Taken from: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next- we use parenthesis
()to definebdiffinstead of{}to limit the scope of the inner functionf, see also: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash
See also: