# 雜湊與校驗和 — MD5、SHA-1、SHA-256、SHA-512

把下載來的檔案和釋出方公佈的那串數字對一下，不用把它發給任何人。

> 計算任意檔案的 MD5、SHA-1、SHA-256、SHA-384 或 SHA-512，並和下載頁面上公佈的校驗和對照。檔案在瀏覽器裡讀取，多大都不會上傳。

本頁是一個完全在你的瀏覽器裡執行的互動式工具，地址是 https://abox.tools/zh-TW/hash-checksum/。你交給它的任何內容都不會被上傳。下面是這個頁面用文字對該工具的全部說明；要使用它，請開啟這個地址。

## 你的檔案**不會上傳**。這裡根本沒有伺服器。

校驗和是對檔案位元組做的一道算術題，而這道題就在這個頁面裡、用你自己這臺裝置的處理器算。檔案按每次 4 MB 從磁碟讀進來，每一塊算過就丟掉，所以任何地方都不會湊出一份完整的副本，記憶體裡不會，伺服器上更不會。這個頁面的另一頭根本沒有伺服器可以接收檔案，就算這裡有什麼東西想發也發不出去。

- ✗ 不上傳
- ✗ 沒有大小上限
- ✓ 斷網也能用
- ✓ 開源
- ✓ 檔案不離開你的裝置

## 怎樣用校驗和核對下載的檔案

1. **選好檔案。** 拖到方框上，或者自己點開選。它會分塊直接從你的磁碟讀進來；這期間沒有任何東西流向別處，也不存在超過多大頁面就放棄的界線。
2. **讓它讀完。** 預設算 MD5 和 SHA-256，一遍讀完一起出。進度條會顯示讀到哪裡了、有多快。一個大的磁碟映象所花的時間，大致就是複製它要花的時間，因為讀的量是一樣的。
3. **把本該是的值貼進來。** 下載頁面給你什麼就貼什麼，什麼形式都行：光是十六進位、`sha256sum` 的一行輸出、整份 `SHA256SUMS` 檔案，或者從 script 標籤上扒下來的 `integrity` 屬性。是哪種演算法由長度決定，對應的那個勾會自己打上。
4. **看那句話，別只看顏色。** 頁面會用一句話告訴你，這是不是那串校驗和所描述的檔案。對得上，說明位元組和釋出方量過的一模一樣；對不上，說明不是，那就先重新下載，再談開啟。
5. **需要的話把校驗和帶走。** 複製一個、全部複製，或者存成一個小文字檔案。存的是命令列工具那種把演算法名寫在前面的格式，這樣演算法名會跟著數字一起走。

## 說得更細的版本

[怎樣用校驗和核對下載的檔案](https://abox.tools/zh-TW/guides/verify-a-file-checksum/): 在 Windows、macOS、Linux 或瀏覽器裡比對 MD5 與 SHA-256 校驗和的辦法，對上了究竟證明了什麼，以及那個讓整件事白做的錯誤。

## 工具箱裡還有

- [密碼與密碼短語產生器](https://abox.tools/zh-TW/password-generator/): 在這裡產生，由你自己的瀏覽器產生，不發往任何地方。什麼都不儲存，也沒有歷史記錄。
- [JSON 格式化](https://abox.tools/zh-TW/json-formatter/): JSON、XML、HTML、CSS 和 YAML，格式化或轉換。沒有一個字被貼進別人的伺服器。
- [YAML 轉 JSON](https://abox.tools/zh-TW/yaml-to-json/): 兩個方向都有，而且會告訴你各自的代價。這些都不會貼進別人的伺服器。
- [XML 格式化](https://abox.tools/zh-TW/xml-formatter/): 排開了好讀的 XML，壓平了好發的 XML，還有兩個方向的 JSON 轉換。這些都不會貼進別人的伺服器。

## 常見問題

### 我的檔案會被上傳到什麼地方嗎？

不會。是你自己的瀏覽器從你的磁碟上讀，你自己的處理器按每次 4 MB 去算。這個工具沒有服務端，頁面的 `Content-Security-Policy` 列出了它可以連的每一個地址，沒有一個是我們的。斷開網路，它照樣能用。

### 有大小上限嗎？

沒有。檔案從不整個待在什麼地方：分塊讀，每一塊算過就丟掉，所以四十吉位元組的磁碟映象和一個文字檔案用的是同樣的幾 MB 記憶體。要花的是時間，而花多少，頁面會一邊跑一邊告訴你。 \
\
這也正是這些演算法寫在這裡、而不是交給瀏覽器的 `crypto.subtle.digest` 的原因，儘管後者更快。那個呼叫要把整段訊息放進一個緩衝區，沒有辦法把檔案分塊餵給它。用了它，能校驗的最大檔案就要看這個分頁碰巧分到多少記憶體。在手機上那是幾百 MB，而人們最想校驗的恰恰是磁碟映象。

### 校驗和對上了，這到底證明了什麼？

證明你磁碟上的這些位元組，就是某個人寫下那串數字時手邊的那些位元組。僅此而已，而這條界線值得說清楚。 \
\
它證明了下載沒有被截斷、沒有被壞盤弄髒、沒有在路上被掉包。它**沒有**證明這個檔案無害，因為釋出方量惡意軟體也一樣準。而如果這串校驗和是和檔案從同一個頁面、同一條連線過來的，那它證明的東西就很少了：能改掉其中一個的人，也能改掉另一個。校驗和最值錢的時候，是它走的路和檔案不同的時候：一份帶簽名的 `SHA256SUMS`、發行版的釋出公告、第二個映象，或者一個本來就知道這個值的包管理器。

### 對不上，那現在怎麼辦？

先從同一個地方重新下一次。斷掉或者續傳過的傳輸是遙遙領先的頭號原因，第二份副本通常就把事情了結了。 \
\
如果第二份給出同樣錯誤的結果，檢查你比的是不是那一行：釋出頁面上會列好幾個檔案，ARM 構建的校驗和永遠不會和 x86 的對上。然後檢查版本號。這些都沒問題卻還是對不上，那就別開啟這個檔案。換一個映象取一份，把兩份的校驗和彼此對一下。

### 我該用哪一種？

用釋出方公佈的那一種。這件事的意義就在於和他們的數字對照，而他們那一份你替不了。 \
\
如果你是在產生校驗和而不是核對校驗和，用 SHA-256。MD5 和 SHA-1 在要緊的那個意義上已經破了：可以刻意造出兩個不同卻同值的檔案，MD5 只要幾小時， SHA-1 也只要不算高的花費。這不等於它們對付意外也沒用了，畢竟一次截斷的下載不會碰巧和原文同值；但它們確實不能再告訴你沒人動過手腳。SHA-384 和 SHA-512 都很好，實際用起來也不見得更好；它們在這裡，是因為有些專案公佈的是它們。

### 既然 MD5 破了，為什麼還留著？

因為印在頁面上的還是它。映象站、韌體下載、高校的軟體頁面，還有非常多廠商的網站，二十年前放了一個 MD5 就再沒動過那一頁。一個拒絕計算它的工具，等於拒絕回答訪客真正帶著來的那個問題。 \
\
它能做的是說清楚這個答案值多少，勾選框旁邊那一行就是在做這件事。對上的 MD5 依然排除了一次損壞的下載，只是排除不了一次蓄意的調包。

### 比對框裡可以貼哪些格式？

常見的都行，而且是哪一種由頁面自己認出來。 \
\
光是十六進位，中間有沒有空格都行。`md5sum` 或 `sha256sum` 的一行輸出，後面跟著檔名也行。整份四十行的 `SHA256SUMS` 檔案也行，這時用的是寫著你這個檔名的那一行。 BSD 那種寫法 `SHA256 (disk.iso) = …` 也行。前面帶標籤的 `SHA-256: …` 也行。還有 subresource integrity 屬性 `sha384-…`，那是 base64 而不是十六進位，比對前會先解碼。 \
\
是哪種演算法由長度決定：32 個十六進位字元是 MD5，40 個是 SHA-1，64 個是 SHA-256，96 個是 SHA-384，128 個是 SHA-512。沒有兩種長度相同，所以既沒有什麼可選，也沒有什麼可選錯。

### 結果會和 sha256sum 或 certutil 一樣嗎？

一樣，一個位元組都不差。這些是有公開測試向量的嚴格規範，這裡的每一種演算法在每次構建時都會拿那些向量和作業系統的實現兩頭核對。 \
\
唯一看得出的差別是顯示方式。Windows 的 `certutil -hashfile` 用大寫並且帶空格，這個頁面用小寫，因為幾乎所有釋出方用的都是小寫。比對時兩邊都不看大小寫和空格，所以從 certutil 裡複製來的校驗和，和貼在這裡的小寫值一樣能對上。

### 可以把兩個檔案互相比對嗎？

可以，多一步而已：先校驗第一個檔案，複製它的校驗和，再選第二個檔案，把那串校驗和貼進框裡。兩個檔案相同的話，頁面會告訴你。 \
\
這一手值得記住，因為校驗和最不動聲色也最擅長的正是這種場合：備份盤上的那一份，究竟是不是筆記本上的同一個檔案，而兩邊都聲稱大小相同、日期相同。

### 它會改動我的檔案嗎？

不會。這個工具只讀。沒有輸出檔案，沒有重新編碼，也沒有什麼會被寫回去：唯一能下載的是一個列著校驗和的小文字檔案。你的原件原封不動地留在磁碟上，這同樣是「關掉分頁會怎樣」這個問題的誠實答案。

### 免費嗎？要不要帳號？

免費，沒有帳號、沒有註冊、沒有試用期。檔案大小沒有上限，校驗多少個也沒有上限。網站上有廣告，那是維持它的錢；廣告拿不到關於你檔案的任何東西。

### 斷網還能用嗎？

能。把頁面載入一次，然後斷開網路，它照樣工作。這也是證明什麼都沒有上傳的最簡單辦法：一個把你的檔案發出去算的工具，會在你拔掉網線的那一刻停住。

## 這條隱私承諾怎麼核實

- **你的檔案沒有出去的路。** Content-Security-Policy 裡列著這個頁面能連的每一個地址，其中沒有一個是我們的。這裡不存在一個能把你的檔案收上去的端點，就算有，程式碼裡也沒有任何一處會把它送過去。這一行從前寫的是 `connect-src 'none'`，那是不打折扣的；廣告換掉了那一句，把這件事講出來也是約定的一部分。
- **檔案從不整個待在什麼地方，多大都一樣。** 它按每次 4 MB 讀進來，每一塊並進正在進行的狀態後就丟掉。所以這個頁面佔的記憶體，四十吉位元組的磁碟映象和一個文字檔案是一樣的，也不存在超過多大就放棄的界線。瀏覽器內建的 `crypto.subtle.digest` 沒有被用上，原因也在這裡：那個函式要求整個檔案一次性進記憶體，而那正是這個工具不想要的天花板。
- **五種演算法，這個儲存庫裡的五個檔案。** `src/md5.js`、`src/sha1.js`、`src/sha256.js` 和 `src/sha512.js` 是把公開的規範照著寫下來，每個大約六十行，常數表是寫出來的而不是算出來的，好讓結果不會因為瀏覽器不同而不同。每一種在每次構建時都會拿官方測試向量和作業系統自己的實現兩頭核對。
- **你貼進來的校驗和也哪裡都不去。** 比對就在這個頁面裡進行，比的是這裡算出來的值。這次比對沒有人會知道：不知道那個值，不知道對沒對上，也不知道檔名。這件事比聽起來要緊：一個校驗和加上一個檔名，就等於告訴收走它的人，你剛剛下載的是哪個軟體的哪一個構建。
- **谷歌載入了什麼，又拿不到什麼。** 廣告和統計指令碼來自谷歌。這兩者都拿不到關於你檔案的任何東西：檔案、檔名、大小，以及算出來的任何一個值，都沒有。每一行讀取或處理位元組的程式碼都由本站提供，並且都在儲存庫裡。
- **贊助按鈕載入了什麼，又拿不到什麼。** 頁首那個「Buy me a coffee」按鈕由 cdnjs.buymeacoffee.com 的指令碼畫出來，字型取自 Google Fonts。它只是一個連結：不上報訪問，也拿不到關於你或你檔案的任何東西。你不點它就什麼都不會發生，點開之後到的是別人的網站。
- **斷網也能用。** 斷開網路，這個頁面的每一部分照舊工作。這是最簡單的一條證據：一個把你的檔案發出去算的工具，會在你拔掉網線的那一刻停住。

**你可以自己核對。**上面這些不用你信。這個頁面是儲存庫裡的模板和配置產生出來的，構建指令碼你能讀，也能自己跑一遍，跑出來的結果就提交在 `dist` 分支上。拿實際發給你的內容，跟你自己從原始碼構建出來的結果對一遍就知道了： https://github.com/A-Box-of-Tools/website

最值得先讀的幾個檔案：`config/site.toml` 裡是 Content-Security-Policy，四個壓縮函式分別在 `src/md5.js`、`src/sha1.js`、`src/sha256.js` 和 `src/sha512.js`，它們共用的填充在 `src/blocks.js`，把檔案分塊讀進來的那個迴圈在 `src/hash.js`。這些檔案裡沒有一行能夠碰到網路。
