題 如何在Linux中比較二進製文件?


我需要比較兩個二進製文件並獲取表單中的輸出

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

對於每個不同的字節。因此,如果 file1.bin 是

  00 90 00 11

以二進制形式和 file2.bin 是

  00 91 00 10

我希望得到類似的東西

  00000001 90 91
  00000003 11 10

實現目標的最簡單方法是什麼?標準工具?一些第三方工具?

(注意: cmp -l 應該用火來殺死,它使用十進制系統進行偏移,八進制使用字節。)


258
2018-03-29 15:28


起源


你基本上在尋找“二元差異”。我可以想像一些令人傷心的命令行單線 od... - quack quixote
@quack quixote:單線的醜陋是什麼? ;) - Bobby
xdelta.org工作得很好。也許看看它是值得的。 - thatjuan
因為你無法回答 這個問題 (因為你不是用戶),我投票結束。這裡明確要求的二進制差異並不是很有用,我傾向於認為你想要一些有用的東西, 如果你在文件的開頭插入一個字節應該將所有字節標記為不同? 不知道這一點,這太模糊了。 - Evan Carroll
更不用說這是明確反對多個領域的規則,它是關於 “編程和軟件開發” 而且你要求的是產品或推薦,而不是如何 使用 特定產品。 - Evan Carroll


答案:


這將以十六進制打印偏移量和字節:

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'

或者做 $1-1 讓第一個打印的偏移量從0開始。

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1-1, strtonum(0$2), strtonum(0$3)}'

不幸, strtonum() 特定於GAWK,因此對於awk的其他版本 - 例如,mawk-您將需要使用八進製到十進制的轉換函數。例如,

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)}'

因可讀性而破裂:

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)
          }'

146
2018-03-29 16:30



@gertvdijk: strtonum 是GAWK特有的。我相信Ubuntu以前使用GAWK作為默認值,但在某些時候切換到了 mawk。在任何情況下,都可以安裝GAWK並將其設置為默認值(另請參閱 man update-alternatives)。有關不需要的解決方案,請參閱我的更新答案 strtonum。 - Dennis Williamson


〜嘎嘎 指出:

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

然後

 % diff b1.hex b2.hex

要么

 % vimdiff b1.hex b2.hex

143
2018-03-29 16:07



在Bash: diff <(xxd b1) <(xxd b2) 但是這個(或你的)的輸出格式遠不及OP所要求的。 - Dennis Williamson
使用vimdiff,它將為兩個“文件”不同的行中的字節著色 - akira
噢,為什麼我沒想到呢?而且我確信我過去也使用過這種技術。 - njd
這對我很有用(有 opendiff 在OS X而不是 vimdiff) - 默認視圖 xxd 提供保持差異引擎在軌道上比較逐字節。使用普通(原始)十六進制簡單地與列配合 fold, diff 會嘗試在我比較的文件中折疊/分組隨機內容。 - natevw
此命令不適用於刪除字節添加,因為後面的每一行都將未對齊並被視為已修改 diff。解決方案是每行放1個字節並刪除地址列,如下所示 約翰勞倫斯阿斯普登 和 我。 - Ciro Santilli 新疆改造中心 六四事件 法轮功


嘗試 diff 在以下zsh / bash進程替換和組合的組合中 colordiff 在CLI中:

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

哪裡:

  • -y 並排顯示差異(可選)
  • xxd 是CLI工具,用於創建二進製文件的hexdump輸出
  • colordiff 會著色 diff 輸出(安裝途徑: sudo apt-get install colordiff
  • -W200 至 diff 更廣泛的產出

提示:

  • 如果文件很大,請添加限制(例如 -l1000)每個人 xxd

樣本輸出:

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


65
2017-09-05 21:14



命令可以簡化為 colordiff -y <(xxd foo1.bin) <(xxd foo2.bin)。 - golem
如果你沒有colordiff,這將做同樣的事情沒有顏色: diff -y <(xxd foo1.bin) <(xxd foo2.bin) - Rock Lee
如果您只想知道兩個文件是否實際相同,可以使用 -q 要么 --brief switch,僅在文件不同時顯示輸出。 - Stefan van den Akker
創建一個功能 xxddiff 為此: xxddiff() ( f() ( xxd "$1" ; ); diff -y <(f "$1") <(f "$2") | colordiff; ) - rubo77
大!仍然, diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim -  會做好工作 - ribamar


有一個叫做的工具 DHEX 哪個可以完成這個工作,還有一個叫做的工具 VBinDiff

對於嚴格的命令行方法,請嘗試 JDIFF


48
2018-03-29 15:41



DHEX很棒,比較二進製文件是你想要做的。將它輸入兩個文件,它可以直接進入比較視圖,突出顯示差異,輕鬆移動到下一個差異。此外,它還可以與大型終端配合使用,這在寬屏顯示器上非常有用。 - Marcin
我更喜歡VBinDiff。 DHEX即使在閒置時也在使用CPU,我認為它一直在重繪。但VBinDiff不適用於寬端子。但是無論如何,地址變得很奇怪,因為每行超過16個字節。 - Janus Troelsen
vbindiff讓我們實際編輯文件,thx! - Aquarius Power
遇到第一個不同的字節後,@ DanielBeauyat壓縮文件會完全不同。輸出可能不太有用。 - Mark Ransom
@ 1111161171159459134 jdiff是程序“套件”的一部分,用於同步和修補jdiff發現的差異。但是,正如Mark Ransom所說,壓縮文件通常不明智;例外情況是“可同步”的壓縮格式(如gzip --rsyncable生成的那樣),其中未壓縮文件中的微小差異應對壓縮文件產生有限的影響。 - hmijail


用於字節添加/刪除的方法

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

通過單個刪除字節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

輸出:

64d63
<  40

如果您還想查看該字符的ASCII版本:

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

bdiff file1 file2

輸出:

64d63
<   40   @

在Ubuntu 16.04上測試過。

我更喜歡 od 過度 xxd 因為:

  • 是POSIXxxd 不是(附帶Vim)
  • -An 刪除地址列沒有 awk

命令說明:

也可以看看:


25
2018-04-04 20:31





簡短的回答

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

使用hexdumps和text diff來比較二進製文件時尤其如此 xxd,字節的增加和刪除成為尋址的變化,這可能使其難以看到。此方法告訴xxd不輸出地址,並且每行只輸出一個字節,這反過來又顯示哪些字節被更改,添加或刪除。您可以稍後通過在更“正常”的hexdump(輸出中)中搜索有趣的字節序列來查找地址 xxd first.bin)。


13
2018-04-22 12:10



(當然,有人可以使用 diff 代替 vimdiff。) - VasyaNovikov


我建議使用hexdump將二進製文件轉儲為文本格式,將kdiff3轉換為差異查看。

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex

11
2018-06-12 07:46



即使在這裡打擊 kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin) 無需創建文件 myfile1.hex 和 myfile2.hex。 - Hastur


hexdiff 是一個旨在完成您正在尋找的程序。

用法:

hexdiff file1 file2

它將兩個文件的十六進制(和7位ASCII)一個顯示在另一個上面,並突出顯示任何差異。看著 man hexdiff 用於在文件中移動的命令,以及一個簡單的命令 q 會退出。


4
2017-10-07 04:11



但是當談到比較部分時,它做得非常糟糕。如果在文件中插入一些字節,則會將所有字節標記為更改 - Murmel
在Ubuntu 16.4上無法通過apt-get獲得和hexdiff - rubo77
@Murmel,雖然我同意,這不是在這裡問的是什麼? - Evan Carroll
@EvanCarroll是真的,因此我留下了一個評論(僅)並沒有downvote - Murmel
我也沒有拒絕投票米克,但我同意你並在這裡回答 superuser.com/a/1373977/11116 因為這個糟糕的問題似乎很可能會被改革或關閉。 - Evan Carroll