Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I need to compare two binary files and get the output in the form

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

for every different byte. So if file1.bin is

  00 90 00 11

in binary form and file2.bin is

  00 91 00 10

I want to get something like

  00000001 90 91
  00000003 11 10

What is the easiest way to accomplish the goal? Standard tool? Some third-party tool?

(Note: cmp -l should be killed with fire, it uses a decimal system for offsets and octal for bytes.)

share|improve this question
you're basically looking for "binary diff". i can imagine some reeeally ugly commandline one-liner with od... – quack quixote Mar 29 '10 at 15:36
@quack quixote: What's ugly about a one-liner? ;) – Bobby Mar 29 '10 at 16:50 works quite well. Perhaps it'd be worth having a look at it. – thatjuan Oct 10 '13 at 5:31

11 Answers 11

up vote 95 down vote accepted

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 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)
share|improve this answer
Unfortunately, this gives me awk: line 2: function strtonum never defined errors on Ubuntu 12.04. Specific AWK implementation perhaps? – gertvdijk Jul 4 '13 at 15:59
@gertvdijk: strtonum is specific to GAWK. I believe Ubuntu previously used GAWK as the default, but switched at some point to mawk. In any case, GAWK can be installed and set to the default (see also man update-alternatives). See my updated answer for a solution that doesn't require strtonum. – Dennis Williamson Jul 4 '13 at 18:08
I added printing the original character and put it into the mc menu, I had to double the % signs: cmp -l %d/%f %D/%f | gawk '{printf "%%08X %%02X %%02X %%c %%c\n", $1-1, strtonum(0$2), strtonum(0$3), strtonum(0$2), strtonum(0$3)}' – 18446744073709551615 Apr 22 '14 at 10:10

As ~quack (hehe) pointed out:

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

And then

 % diff b1.hex b2.hex


 % vimdiff b1.hex b2.hex
share|improve this answer
In Bash: diff <(xxd b1) <(xxd b2) but the output format of this (or yours) is nowhere near what the OP asked for. – Dennis Williamson Mar 29 '10 at 16:33
with vimdiff it is, it will color the bytes in the lines where the two 'files' differ – akira Mar 30 '10 at 4:45
Aww, why didn't I think of that? And I'm sure I've used this technique in the past too. – njd Mar 30 '10 at 17:37
Nice. I'm on an embedded system that uses BusyBox and there is no cmp, but hexdump + diff works like a charm. – Robert Calhoun Mar 22 '13 at 3:47
This worked great for me (with opendiff on OS X instead of vimdiff) — the default view xxd provides keeps the diff engine on track comparing byte-by-byte. With plain (raw) hex simply column-fit with fold, diff would try to fold/group random stuff in the files I was comparing. – natevw Nov 15 '14 at 23:26

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 JDIFF.

share|improve this answer
DHEX is awesome is comparing binaries is what you want to do. Feed it two files and it takes you right to a comparative view, highlighting to differences, with easy ability to move to the next difference. Also it's able to work with large terminals, which is very useful on widescreen monitors. – Marcin Sep 8 '11 at 0:08
I prefer VBinDiff. DHEX is using CPU even when idling, I think it's redrawing all the time or something. VBinDiff doesn't work with wide terminals though. But the addresses become weird with wide terminals anyway, since you have more than 16 bytes per row. – Janus Troelsen Oct 17 '12 at 14:22
vbindiff lets us actually edit the file, thx! – Aquarius Power Sep 16 '14 at 18:28
@DanielBeauyat compressed files will be completely different after you encounter the first different byte. The output is not likely to be useful. – Mark Ransom Aug 5 '15 at 3:12
@1111161171159459134 jdiff is part of a "suite" of programs to sync and patch the differences found by jdiff. But, as Mark Ransom said, that would be generally not wise on compressed files; the exception is "synchronizable" compressed formats (like that produced by gzip --rsyncable), in which small differences in the uncompressed files should have a limited effect on the compressed file. – hmijail Feb 13 at 11:12

Try diff in the following combination of zsh/bash process substitution and colordiff in CLI:

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


  • -y shows you differences side-by-side (optional)
  • xxd is CLI tool to create a hexdump output of the binary file
  • colordiff will colorize diff output (install via: sudo apt-get install colordiff)
  • add -W200 to diff for wider output


  • if files are to big, add limit (e.g. -l1000) for each xxd

Sample output:

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

share|improve this answer
Command can be simplified as colordiff -y <(xxd foo1.bin) <(xxd foo2.bin). – golem Nov 17 '15 at 22:46

Method that works for byte addition / deletion

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

Output for a single NUL byte removal at the 100th byte of a large file:

< 00

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

Sample output:

<   00   \0

Tested on Ubuntu 14.04.

I prefer od over xxd because:

  • it is POSIX, xxd is not (comes with Vim)
  • has the -An to remove the address column without awk.

Command explanation:

  • -An removes the address column. This is important otherwise all lines would differ after a byte addition / removal.
  • -w1 puts 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.
  • -tx1 is the representation you want, change to any possible value, as long as you keep 1 byte per line.
  • -v prevents asterisk repetition abbreviation * which might interfere with the diff
  • paste -d '' - - joins every two lines. We need it because the hex and ASCII go into separate adjacent lines. Taken from:
  • we use parenthesis () to define bdiff instead of {} to limit the scope of the inner function f, see also:
share|improve this answer

I'd recommend hexdump for dumping binary files to textual format and kdiff3 for diff viewing.

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex
share|improve this answer
Even here in bash kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin) with no need to create files myfile1.hex and myfile2.hex. – Hastur Jan 25 at 14:34

Short answer

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

When using hexdumps and text diff to compare binary files, especially xxd, the additions and removals of bytes become shifts in addressing which might make it difficult to see. This method tells xxd to not output addresses, and to output only one byte per line, which in turn shows exactly which bytes were changed, added, or removed. You can find the addresses later by searching for the interesting sequences of bytes in a more "normal" hexdump (output of xxd first.bin).

share|improve this answer
(Of course, one may use diff instead of vimdiff.) – Vasya Novikov Dec 15 '15 at 17:35

It may not strictly answer the question, but I use this for diffing binaries:

gvim -d <(xxd -c 1 ~/file1.bin | awk '{print $2, $3}') <(xxd -c 1 ~/file2.bin | awk '{print $2, $3}')

It prints both files out as hex and ASCII values, one byte per line, and then uses Vim's diff facility to render them visually.

share|improve this answer

The hexdiff is a program designed to do exactly what you're looking for.


hexdiff file1 file2

It displays the hex (and 7-bit ASCII) of the two files one above the other, with any differences highlighted. Look at man hexdiff for the commands to move around in the file, and a simple q will quit.

share|improve this answer
But it does a pretty bad job when it comes to the comparing part. If you insert some bytes into a file, it will mark all byte afterwards as changes – user1885518 Apr 27 at 19:43

BinDiff is a great UI tool for comparing binary files that has been open sourced recently.

share|improve this answer
Can it be used on arbitrary binary files, though? That page seems to indicate that it's only useful for comparing executables that have been disassembled by Hex-Rays IDA Pro. – eswald Apr 29 at 22:57

I recommend IDA Pro to analyse the binary files. Comparison can then be done using a plug-in for IDA such as BinDiff.

share|improve this answer
I would have to buy to test it right? – Aquarius Power Sep 16 '14 at 18:17
@AquariusPower Not necessarily, IDA Pro does have a Free Version – user3119546 Sep 19 '14 at 1:19
but it is not for linux! :( – Aquarius Power Sep 19 '14 at 20:08
I've used quite a few different free versions of IDA Pro under Wine without issues, if I recall correctly. – doshea May 17 '15 at 5:42
This has been open sourced recently… – Evgeny Mar 23 at 20:17

You must log in to answer this question.