# Binary Diff

> 在瀏覽器裡比對兩個二進位檔案：同步雙欄 hex 檢視標出差異、差異區段列出 offset 可直接跳、還有相同率百分比。大檔用分塊雜湊定位差異區，全程不上傳。

- URL: https://bytescope.dev/zh-Hant/binary-diff/
- Locale: zh-Hant · Also: [en](https://bytescope.dev/en/binary-diff.md) · [ja](https://bytescope.dev/ja/binary-diff.md)
- Runs: 檔案不會離開你的瀏覽器 — 全部在本機處理。
- Requires: Any modern browser (Chrome, Edge, Firefox, Safari), desktop and mobile.
- Updated: 2026-09-08

## What it does

兩包本來應該 byte 完全一樣的韌體，結果不一樣。一個從不太可靠的傳輸拿到的檔案，旁邊擺著它本來該對上的原檔。裝置寫入前和寫入後各 dump 一次的設定區塊。這三件事要問的都是同一句話，而且是 checksum 死都不會回答你的那一句：哪些 byte 變了，變在哪裡。兩個檔案丟進來，你會拿到每一處差異的 offset、每段差異連續多長，還有實際的 byte 左右並排——`0x1F40` 從「雜湊對不上」變成一個你可以走過去看的位置。

檔案不上傳。這句話這站到處都在講，但在這頁它是真的會左右你要不要用：真正需要比對的檔案，就是還沒發表的韌體映像、客戶資料的 dump、以及從出問題那台機器撈出來的磁碟映像。任何叫你把兩包 build 成品交出去的網站，要的剛好是最不能給的兩樣東西。這頁是靜態檔案，比對跑在你自己機器上的 Web Worker 裡，兩個檔案都用 File API 直接從磁碟讀。這頁背後沒有伺服器可以送，所以「只在瀏覽器裡跑的 binary diff」跟任何要你上傳的服務，根本是兩回事。

大檔的做法是——大部分根本不讀。先把兩個檔案分塊算雜湊，雜湊對上的區塊不必逐 byte 看就知道一樣，只有對不上的區域才會真的讀進來細比。所以比兩顆 500 MB 的映像，不代表要把 1 GB 塞進記憶體；兩包只差在內嵌版本字串的 build，大概讀完磁碟就比完了。雙欄檢視沿用 hex editor 那套虛擬滾動，只組畫面上看得到的那幾列，所以就算是 2 GB 的映像，滑起來一樣順。

也把話說清楚：逐 byte 的差異比對不是文字 diff，它不會幫你重新對齊。在檔案開頭附近插進 1 個 byte，後面每個 byte 都往後挪一格，這時工具會老實告訴你「幾乎整份檔案都不一樣」——在 byte 這個層級完全正確，可是拿來描述你剛做的那個編輯就毫無用處。這裡沒有什麼自動對齊的魔法，硬要裝有反而會讓整份輸出不能信。不過它報的東西還是有用：以比對過的 byte 位置算出的相同率、點一下就跳到任一差異區段的清單，以及兩個同步、跟 hex editor 一樣是 offset/hex/ASCII 版面的欄位——「只是整份位移、內容其實一樣」這種狀況，你會親眼看到，而不是被一個百分比蓋掉。

## Limits

Does not produce or apply patches and does not diff text semantically; it compares two files byte by byte.

## FAQ

### 我的檔案會被上傳嗎？

不會。兩個檔案都是用 File API 在本機開啟，再用 `Blob.slice()` 分塊讀取，雜湊計算和 byte 比對都在你瀏覽器裡的 Web Worker 完成。這頁本身是靜態檔案，背後沒有 API，所以連個可以上傳的地方都不存在。這正是這個工具的重點：還沒出貨的韌體，跟客戶那份壞掉的資料庫，剛好就是最需要比對、又最不想丟到別人伺服器上的兩種檔案。

### 為什麼只插了 1 個 byte，差異卻大到誇張？

因為逐 byte 比對是位置 0 對位置 0、位置 1 對位置 1 這樣比的。在 offset 16 插進 1 個 byte，16 之後的每個 byte 都往後挪一格，從那裡開始幾乎全部對不上，工具就會報出一段一路延伸到檔尾的差異。它沒有騙你——那些 byte 位置裡真的放著不同的值——只是這不是人類想要的答案，因為人類會說那叫「改了 1 個 byte」。如果檔案偏文字，該用的是行為單位的 diff；如果是二進位，那就看差異從哪個 offset 開始：那裡就是插入點，通常也就是你真正要找的那個事實。

### 兩個長度不同的檔案是怎麼比的？

重疊的範圍逐 byte 比，只有一邊才有的尾端會當成一段差異報出來，附上 offset 和長度，不會默默丟掉。相同率是拿比較長的那個檔案當分母，所以 1 MB 的檔案後面又接了 1 MB，分數大概是 50% 而不是 100%——多接上去的資料是真的差異，算成完全相同才更誤導人。長度不一致本身也會單獨標出來，因為同一份韌體的兩包 build，這通常是第一個想知道的事。

### 最大可以比多大的檔案？

大到瓶頸是磁碟速度、不是記憶體。兩個檔案都不會整份載入：先用分塊雜湊定位出對不上的區域，只有那些區域會被讀進來細比，hex 雙欄也只畫畫面上的那幾列。單邊幾百 MB 是日常，好幾 GB 的磁碟映像也跑得動——第一輪得把兩個檔案整份流過雜湊，所以磁碟要多久餵完就得等多久。瀏覽器分頁本身有記憶體上限，這也正是這裡從頭到尾都不打算把整顆映像抱在手上的原因。

### 除了 hex，可以用 ASCII 看差異嗎？

可以。每一欄都跟 hex editor 一樣有 offset、hex、ASCII 三個欄位，高亮同時打在 hex 的 byte 和對應的 ASCII 上，所以內嵌字串或檔案路徑裡的改動，就在它發生的位置直接以文字讀出來。要確認一個你本來就懷疑的差異，這往往是最快的路：build 時間、版本號、序號在 ASCII 欄會是看得懂的字，而 hex 欄只會給你一堆動過的 byte。

### 相同率到底在算什麼？

算的是「值相同的 byte 位置」佔多少比例，分母是比較長那個檔案的長度。沒有更聰明的處理，所以好推理，也一樣好誤讀。兩個長度相同但毫無關係的檔案，光靠運氣也會落在 0.4% 上下，因為任兩個隨機 byte 有 256 分之 1 的機會相同；而開頭插了 1 個 byte 的檔案，內容幾乎一模一樣，分數卻可能只剩個位數。把它當成跟差異區段清單一起看的快速體檢就好——99.98% 加三段很短的區段，那是改了個字串；6% 那是另一個檔案——想要真正的答案，去讀 offset。
