CRC32 校驗碼是 CRC-32/ISO-HDLC 循環冗餘檢查所產生的 32 位元輸出,以恰好八個小寫十六進位數字表示,例如 ASCII 字串 123456789 對應的 cbf43926。這個八位數值並非較長雜湊的縮寫、也不是截斷的指紋、更不是安全性權杖;它是在輸入位元組上執行特定 polynomial 除法所得到的完整結果,再以前置零格式化,使輸出長度始終固定。本站上的 CRC32 計算機正是從 UTF-8 文字或明確的十六進位位元組產生該八位數值,使用與 gzip、ZIP、PNG 及許多其他格式在其標頭中所內含的相同反射 polynomial (0xEDB88320)、初始暫存器 (0xFFFFFFFF)、反射位元組處理,以及最終 XOR (0xFFFFFFFF)。了解這八位數字實際代表什麼、以及不代表什麼,正是成功完整性檢查與誤導性檢查之間的差別。

calculate crc32 checksum
計算 CRC32 校驗碼並比對 8 位十六進位數字

CRC32 校驗碼是什麼(以及不是什麼)

校驗碼是從較長的資料區塊所衍生出的一個簡短且具確定性的值。當資料變動時,校驗碼也會跟著變動;當資料逐位元組完全相同,並以相同的演算法與相同的參數處理時,所得的校驗碼也會相同。CRC32 是校驗碼家族中一個特定的成員,其輸出恰好為 32 位元,大到足以讓隨機碰撞相當罕見,但小到足以輕鬆放進檔案標頭或網路封包之中。

CRC32 中的「32」代表結果的位元寬度。「循環冗餘」部分則描述其數學原理:輸入的位元組被視為一個 polynomial 的係數,並對一個固定的生成 polynomial 進行模 2 除法。該除法的餘數即為校驗碼。由於此運算在 GF(2) 上是線性的,因此同一個演算法對同一個位元組序列必定產生相同的輸出,而兩個不同的序列幾乎總是會產生不同的餘數,但並非絕對,因為輸出空間僅有 2^32。

CRC32 計算機運算的是該家族中的一個特定成員:CRC-32/ISO-HDLC,亦稱為 CRC-32/IEEE,在非正式文件中偶爾只簡稱為「CRC32」。它所回傳的八位小寫十六進位字串(例如 cbf43926)即為完整的校驗碼,並以前置零格式化,使數值無論多小,長度始終為 8 個字元。前置零是答案的一部分;在與已發布的規格進行比對時,像 0a3b1c4d 這樣的輸出與 a3b1c4d 並不相同。

如何計算 CRC32 校驗碼

只要知道目標格式所預期的變體,整個流程只需幾個步驟。本頁面實作的是 CRC-32/ISO-HDLC,因此當您需要的就是這個變體時,下面的步驟即適用。

  1. 確認 CRC 變體,以及規格所涵蓋的精確位元組範圍。對大多數封存檔與影像格式而言,這指的是檔案主體本身,但不含儲存的校驗碼欄位;對通訊協定框架而言,則是除了尾端 CRC 位元組之外的所有內容。在 CRC-32/ISO-HDLC 下,ASCII 字串「123456789」的標準檢查值為 cbf43926,因此若您的目標預期不同的值,就代表它使用的是不同的變體。
  2. 開啟 CRC32 計算機,並挑選與您資料相符的輸入模式:人類可讀的字串使用 UTF-8 文字,當您擁有來自通訊協定傾印或二進位檔的精確位元組序列時,則使用十六進位位元組。
  3. 輸入酬載時,必須完全依照目標系統處理該資料的方式。在文字模式下,請記得帶有變音符號的字元、CJK 字元以及表情符號會展開成多個 UTF-8 位元組。在十六進位模式下,貼上時不要加上 0x 前綴,也不要加上逗號;位元組對之間的空白會自動移除。
  4. 點選計算,並讀取八位小寫十六進位數的結果。請將全部八個字元(包括任何前置零)與規格中的預期值進行比對。
  5. 使用複製按鈕複製該值。複製動作僅複製精確的 32 位元值 — 八個字元,沒有前綴、沒有空格、也沒有換行 — 因此可以直接貼入校驗碼檔、腳本或說明文件頁面中。

八位十六進位數值的由來

計算機所使用的精確參數並非任意;它們是 CRC-32/ISO-HDLC 的公開定義值,與 RFC 1952 中針對 gzip 包裝所記載的公式相同,並由 zlib 校驗碼常式、ZIP、PNG 及許多其他容器所採用。下方的參考表列出了各項定義常數以及標準檢查值,方便您與任何嘗試對應的規格進行比對。

參數數值
寬度32 位元
Polynomial(反射)0xEDB88320
初始暫存器值0xFFFFFFFF
輸入反射是(每個位元組 LSB 在前)
輸出反射
最終 XOR0xFFFFFFFF
「123456789」的檢查值0xCBF43926

在機制上,計算機會從反射 polynomial 建構一張 256 項的查詢表。對每個輸入位元組,它會將該位元組與執行中暫存器的低八位元進行 XOR,查詢對應的表項餘數,再與向右移八個位元的暫存器結合。在最後一個位元組處理完畢後,暫存器會與 0xFFFFFFFF 進行 XOR,並以前置零補齊,寫成八個小寫十六進位數字,使輸出長度永遠剛好是八個字元。整個計算過程都在瀏覽器中執行,輸入資料不會被上傳,而複製動作僅會將八位數值放入剪貼簿。

為什麼兩台 CRC32 計算機可能產生不同的結果

現存多種 32 位元 CRC 公式,且彼此容易混淆。不同系統會以 CRC32、CRC-32/ISO-HDLC、CRC-32C、Castagnoli、Koopman、MPEG-2、BZIP2、JAMCRC 等名稱來代表 polynomial、初始暫存器、反射設定或最終 XOR 各不相同的公式。在 ASCII 位元組「123456789」上的標準檢查值 cbf43926,是區分 CRC-32/ISO-HDLC 與其同類變體最可靠的方式:若您計算「123456789」卻得不到 cbf43926,就表示另一套系統採用了不同的變體或涵蓋了不同的位元組範圍。如何挑選正確的變體與位元組來找出 CRC32一文中的變體選擇指南,更詳細地說明了 ISO-HDLC 與 CRC-32C 之間的差異。

除了變體本身之外,有三個位元組處理的細節,經常在功能上相同的計算機之間導致 CRC32 數值不一致:

  • 字元編碼。以 UTF-8 輸入的文字,會產生與 UTF-16、Latin-1 或 Windows-1252 不同的位元組序列。ASCII 字元各佔一個位元組,但帶有變音符號的字母、CJK 字元以及表情符號則可能佔 2、3 或 4 個位元組。以 UTF-16 程式碼單位計算所得的結果,將無法與以等效 UTF-8 位元組計算的結果相符。
  • 換行標準化。不同的作業系統與不同的編輯器,會以 LF、CR 或 CRLF 來儲存行結尾。即使顯示出來的文字看起來相同,底層的位元組序列並不相同,校驗碼自然也不一樣。
  • 十六進位模式的格式。十六進位解析器會移除位元組對之間的空白,但會拒絕 0x 之類的前綴、空白以外的分隔符、註解,以及奇數的尾端半位元組。每兩個十六進位數字恰好構成一個位元組,前導的 00 位元組會被保留,並確實影響結果。當通訊協定提供精確的位元組時,請以十六進位方式貼上,而非將其重新鍵入為可見文字。

若您的首次嘗試未能相符,請在懷疑計算機有 bug之前,先逐一檢查這三個可能造成不符的來源。

CRC32 並非身分驗證

一個正確的 CRC32 校驗碼只能證明一件事:當兩端使用相同的演算法、相同的參數,以及相同的位元組範圍時,您所處理的位元組與原始發布者處理的位元組完全一致。它能以極高的機率偵測出偶發的損壞 — 例如雜訊線路上翻轉的一個位元、被截斷的下載,或是損壞的磁碟磁區。但它無法偵測蓄意的竄改,因為 CRC 是線性的且容易遭到操控:知道預期 CRC32 的攻擊者,可以在線性時間內偽造出具有相同校驗碼的新酬載,而無須破解任何密碼學原始機制。

這種區別在以下三個常見情境中至關重要。請勿使用 CRC32 來驗證某個軟體安裝程式是否來自您所信任的發布者 — 應改用已發布的加密摘要(例如 SHA-256)並搭配經驗證的通道,再透過另一條獨立路徑來確認該摘要。請勿使用 CRC32 來授權來自不受信任裝置的指令、API 請求或韌體更新 — CRC32 無法證明來源。也不要依賴 CRC32 來保護憑證、工作階段權杖或金鑰 — 它不是加密、不是雜湊、不是訊息驗證碼,也不是數位簽章。關於 CRC32 與加密校驗碼在實際封存與傳輸流程中如何搭配使用,如何計算 CRC-32 校驗碼以確保資料完整性一文以具體範例進一步釐清了這道界線。

輸入限制與實用訣竅

計算機最多接受 5,000,000 位元組,以確保在處理長輸入時表格驅動的運算仍能保持流暢。輸出絕不會被靜默截斷:該數值會被視為無符號整數,並永遠以恰好八個十六進位數字呈現,因此即使程式端的空輸入也會產生 00000000,儘管使用者介面會要求輸入資料,這樣一來,意外的空白點擊才不會被誤認為一次有意義的驗證。整個計算過程都在瀏覽器中執行,輸入資料不會被上傳,而複製按鈕僅會複製八位數值。

若您計算所得的八位輸出與預期值不符,最有效率的排查順序為:先透過標準檢查值確認變體,接著確認位元組範圍,最後再確認位元組編碼與換行慣例。計算機僅實作了 CRC-32/ISO-HDLC;若您需要其他 32 位元公式,則必須使用針對該特定變體的工具。