計算 ZIP 封存檔、PNG 影像、gzip 串流,以及大多數內嵌檢查碼的 CRC32 標準做法,是對精確的酬載位元組執行 CRC-32/ISO-HDLC,然後將得到的 32 位元值讀為八個小寫的十六進位數字;對 "123456789" 的九個 ASCII 位元組而言,該值為 cbf43926。知道這個規範的檢查值之後,你就能在信任任何其他結果之前,確認自己執行的是正確的變體、使用的是正確的位元組。CRC32 計算機正是實作了該 ISO-HDLC 變體,並同時提供 UTF-8 文字模式與十六進位位元組模式,讓你能夠符合規格所描述的位元組序列。
大多數搜尋 "calculate CRC32" 的人會想要三種東西其中之一:放入檔案標頭的檢查碼、要與已發布摘要比對的值,或是對已下載酬載所做的健全性檢查。這些工作各自化簡之後,都會回到同一個核心運算:將已知的位元組序列餵入 CRC-32/ISO-HDLC 演算法,再讀出八位數的十六進位結果。問題在於,有數種 32 位元 CRC 公式共用 "CRC32" 這個名稱,它們對相同輸入會產生不同的數字。正確選擇比運算本身更為重要,這就是為什麼這個計算機會把參數固定下來,並在輸入階段就要求你在文字與十六進位之間做選擇,而不是當作隱藏設定。

"Calculate CRC32" 實際上代表什麼
當一個工具說它能 "calculate CRC32" 時,它應該明確指出使用了哪一個 32 位元多項式、哪一個初始暫存器值、以及哪一個最終 XOR。CRC32 計算機實作了 CRC-32/ISO-HDLC,也就是 RFC 1952(GZIP 規格)中所編纂的變體,並被 zlib C 函式庫、ZIP 封存檔、PNG 影像以及許多其他格式所採用。ISO-HDLC 會以最低有效位元優先的方式處理輸入,並對應一個反射式多項式,最後再對暫存器取補數後輸出。
輸出永遠是一個 32 位元數字。按照慣例會以八個小寫十六進位數字來顯示,這就是為什麼前導零很重要:結果 00a1b2c3 與 a1b2c3 並非相同的數字,即使在口語上它們經常被簡化。把任何被引用的 "CRC32" 摘要視為剛好八個十六進位數字,不多也不少,並以小寫字母書寫以與計算機一致。
CRC-32/ISO-HDLC 背後的參數
以下參數定義了這個變體。任何使用不同數值的工具,都在計算一個不同的公式,即使它同樣把輸出稱為 "CRC32"。
| 參數 | 數值 | 意義 |
|---|---|---|
| 寬度 | 32 bits | 暫存器與結果的大小 |
| 反射式多項式 | 0xEDB88320 | 用於建立 256 項的查詢表 |
| 初始暫存器 | 0xFFFFFFFF | 第一個輸入位元組之前的狀態 |
| 輸入反射 | 是(按位元組) | 位元以最低有效位元優先處理 |
| 最終 XOR | 0xFFFFFFFF | 在最後一個位元組之後套用 |
| "123456789" 的檢查值 | 0xCBF43926 | ISO-HDLC 的規範自我測試 |
| 輸出格式 | 8 位數小寫十六進位 | 計算機所顯示的內容 |
如果你對 "123456789" 預期的檢查值不是 cbf43926,表示另一個系統使用了不同的變體(CRC-32C、MPEG-2、BZIP2、Koopman、JAMCRC 或其他),或是不同的位元組範圍。檢查值是最簡單的區分方式,也是在信任工具所產生的任何其他輸出之前,應該最先驗證的事項。
一個實作範例:"123456789"
為了讓參數表更具體,讓我們對一個固定輸入執行該演算法。取 ASCII 字串 "123456789",它是九個位元組,十六進位值為 31 32 33 34 35 36 37 38 39。將暫存器設為 0xFFFFFFFF。對每個位元組,將該位元組與暫存器低位的八位元組做 XOR,從以多項式 0xEDB88320 所建立的 256 項查詢表中查找對應的餘數,再把該餘數與向右移八個位元後的暫存器組合起來。在處理完所有九個位元組之後,將暫存器與 0xFFFFFFFF 做 XOR,並將結果格式化為八個小寫十六進位數字。
結果是 0xCBF43926,書寫為 cbf43926。這就是 CRC-32/ISO-HDLC 已發布的檢查值,並與上方參數表中所列的數值一致。RFC 1952 中以實際範例方法描述了完整的查詢表推導過程,而 zlib 手冊則把同一個演算法記錄為其預設檢查碼,這就是為什麼 "zlib checksum" 與 "CRC-32/ISO-HDLC" 指的是同一個公式。
如何使用 CRC32 計算機來計算 CRC32
CRC32 計算機完全在裝置上執行該演算法,因此你送出的位元組不會離開瀏覽器。固定參數的設計代表你不會意外地滑入不同的變體;你唯一需要選擇的只有輸入模式。
- 從規範格式中找出確切的 CRC 變體以及涵蓋的位元組範圍。本頁實作了 CRC-32/ISO-HDLC,該變體應該會對 "123456789" 的 ASCII 位元組產生 cbf43926。
- 判斷你的酬載應該被解讀為文字,還是原始位元組序列。只有在 UTF-8 明確正確時才選擇文字模式;其餘情況請以十六進位貼上位元組。
- 輸入酬載。文字模式可直接輸入或貼上字串;十六進位模式則需使用偶數個十六進位數字,不可加上前置詞、除了空白以外的分隔符或註解。輸入上限為 5,000,000 位元組,以維持查詢表處理的回應速度。
- 進行計算並讀取八位數小寫十六進位結果。該值會被視為無符號數,絕不會被截斷。
- 將全部八個數字(包括前導零)與預期值逐一比對。將相符視為「無意外錯誤的一致性」證據,而非安全性真實性的證明。
更完整的輸入規則說明,請參閱從文字或十六進位位元組產生 CRC32這份指南。
文字模式與十六進位模式:各自的適用情境
這兩種輸入模式不能互相替代。計算機在處理前會將文字編碼為 UTF-8,因此 ASCII 字串 "123456789" 貢獻的是九個單位元組字元,但字串 "café" 貢獻的是五個位元組(63 61 66 C3 A9),而表情符號 "🧮" 則貢獻四個位元組。如果你的來源使用 UTF-16、舊式字碼頁、Unicode 正規化形式,或不同的換行慣例,文字模式的結果就會與你預期的值不同。
十六進位模式會移除位元組對之間的空白,但仍要求偶數個十六進位數字;每兩個數字構成一個位元組。像 "0x" 這類前置詞、除了空白以外的分隔符、註解以及奇數的尾端半位元組都會被拒絕。前導 00 位元組會被保留,而且確實會影響結果,因此以 null 位元組開頭的酬載與不以此開頭的酬載並不相同。當通訊協定給出精確位元組時,請使用十六進位模式,而不要將其重新打成可見文字。
| 情境 | 建議模式 | 原因 |
|---|---|---|
| 計算摘要以與已發布規格比對 | 十六進位 | 符合規格涵蓋的精確位元組序列 |
| 對記錄行或簡短訊息做雜湊 | 文字(UTF-8) | 直接輸入,無重新編碼風險 |
| 驗證可能包含 NUL 位元組的標頭 | 十六進位 | 保留前導零與任何 null |
| 檢查包含表情符號或 CJK 字元的字串 | 十六進位(先明確做 UTF-8 轉換) | 避免意外的多位元組長度變化 |
解讀八位數輸出並進行比對
計算機會將結果格式化為八個小寫十六進位數字,必要時以前導零補齊。該值會被視為無符號數,因此最大值為 ffffffff。輸出絕不會被悄悄截斷;即使是像 0x00000001 這樣的值,也會顯示為 00000001。空白的程式化輸入其 CRC 為 00000000,不過使用者介面會要求輸入資料,因此不會因為不小心按到空白而看似產生有意義的驗證。
在與已發布摘要比對時,請逐個數字比對。會自動去除前導零、變更大小寫,或在值前面加上 "0x" 的工具,可能會掩蓋不一致之處。將任何無法解釋的差異視為真實的差異;常見的原因包括變體錯誤、位元組範圍錯誤,或換行慣例不同。以 "123456789" 已發布的檢查值進行交叉比對,是在繼續往下之前確認變體一致的最快方法。
CRC32 的不足之處
CRC 是一種循環冗餘校驗,用於偵測資料中常見的意外變更,而非用於認證。CRC32 演算法並非加密、密碼學雜湊、訊息鑑別碼、數位簽章或來源證明。它具線性特質且容易遭到蓄意操控,因此想要特定 CRC 的攻擊者可以在不知道你酬載內容的情況下,產生出相符的位元組。請勿將其用於驗證不受信任的軟體、授權指令、保護憑證,或證明檔案來自可信的發布者。針對對抗式完整性,請依賴像 SHA-256 或 HMAC 這類密碼學摘要,並搭配經認證的發布通道。相關變體細節以及與認證之間的區別,亦可參閱 IETF 的gzip 規格以及zlib 手冊。
其他可能與之混淆的 32 位元變體
許多系統會把 "CRC32" 這個標籤用於多項式不同,或是初始與最終轉換不同的公式。CRC32 計算機僅實作 CRC-32/ISO-HDLC。如果你對 "123456789" 預期的檢查值不是 cbf43926,則另一個系統很可能使用下列變體之一,或涵蓋不同的位元組範圍。
| 變體 | 常用名稱 | 備註 |
|---|---|---|
| CRC-32/ISO-HDLC | CRC32、zlib、PNG、ZIP | 多項式 0xEDB88320;檢查值 cbf43926 |
| CRC-32C | Castagnoli、iSCSI、SCTP | 多項式 0x82F63B78;檢查值 e3069283 |
| CRC-32/MPEG-2 | MPEG-2、BZIP2 | 非反射式多項式 0x04C11DB7;檢查值 0376E6E7 |
| CRC-32/Koopman | Koopman | 多項式 0xEB31D82E;檢查值 765E7680 |
| CRC-32/JAMCRC | JAMCRC | ISO-HDLC 不進行最終 XOR;檢查值 340bc6d9 |
辨識變體很重要,因為在兩個使用不同公式的系統之間交叉比對 "CRC32" 值,必然會失敗。上表中的檢查值欄位,是確認你手上是哪一種的最快方式,也與計算機參數所依據的自我測試相同。
如需更深入的說明,請參閱計算 CRC32 檢查碼並比對 8 個十六進位數字。