ByteScope

Binary Diff

兩包韌體、兩顆磁碟映像、兩份設定 dump 丟進來——逐 byte 比對,全部在你的瀏覽器裡完成。

檔案不會離開你的瀏覽器 — 全部在本機處理。

檔案 A

把檔案 A 拖到這裡

或點一下選檔 — 任何格式、任何大小都行

檔案 B

把檔案 B 拖到這裡

或點一下選檔 — 任何格式、任何大小都行

兩邊都放好檔案就可以比對。

關於這個工具

兩包本來應該 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 版面的欄位——「只是整份位移、內容其實一樣」這種狀況,你會親眼看到,而不是被一個百分比蓋掉。

常見問題

我的檔案會被上傳嗎?

不會。兩個檔案都是用 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。