calculate crc32 of a file
計算檔案的 CRC32:比對 8 位數檢查碼

「計算檔案的 CRC32」實際涵蓋的內容

檔案的 CRC-32/ISO-HDLC 是一個 8 位數的小寫十六進位值,產生方式是將檔案涵蓋的位元組,透過反射多項式 0xEDB88320 進行運算,並使用初始暫存器 0xFFFFFFFF 與最終 XOR 值 0xFFFFFFFF。對於 ASCII 位元組 123456789,標準化的檢查值為 cbf43926,這正是不同實作之間辨識同一變體的方式。因此,「計算檔案的 CRC32」意指決定檔案中哪些位元組屬於涵蓋範圍、將這些位元組轉換為 UTF-8 文字或原始十六進位配對,並產生一個格式化為恰好 8 個十六進位數字(保留前導零)的無符號 32 位元結果。

大多數讀者來到這裡,是因為某個下載頁面、建構腳本或同事在某個檔案旁邊公布了一個像 cbf43926 這樣的值,並要求他們確認是否相符。困難點幾乎從來不是運算本身,而幾乎都是位元組範圍的問題:所公布的值涵蓋的是原始位元組、是標頭加上主體,還是去除了長度欄位的精簡主體?弄錯這一點會產生一個與其他所有工具都不一致的結果,即便每個工具本身都是正確的。

如何使用瀏覽器工具計算檔案的 CRC32

CRC32 計算機接受 UTF-8 文字或精確的十六進位位元組,並以 8 位數小寫十六進位字串的形式回傳 CRC-32/ISO-HDLC 值。運算完全在瀏覽器中進行,輸入內容不會被上傳,而複製動作只會複製 32 位元的值,這讓機密資料不會經過網路傳輸。

  1. 確認所需的 CRC 變體與精確的位元組範圍。本頁面僅實作 CRC-32/ISO-HDLC,亦即 gzip、ZIP、PNG 以及大多數通用封存檔與影像格式所使用的反射多項式 0xEDB88320 變體。
  2. 透過檢查標準值來確認變體:對於 ASCII 位元組 123456789,結果必須為 cbf43926。若預期值不同,表示該系統使用的是不同的 32 位元公式,例如 CRC-32C、Koopman、MPEG-2、BZIP2 或 JAMCRC。
  3. 選擇輸入模式。僅在規格將涵蓋的承載資料描述為字串時,才選擇 UTF-8 文字;當規格將承載資料描述為精確的位元組、標頭、長度欄位或儲存的 CRC 位元組時,則選擇十六進位位元組。
  4. 準確輸入承載資料。十六進位模式會忽略位元組配對之間的空白,但要求位數為偶數、拒絕 0x 前綴與奇數的尾端半位元組,並保留前導的 00 位元組。
  5. 進行計算,然後將結果的全部 8 位數與預期值進行比對,包括前導零。比對相符只能證明在偶發錯誤方面的一致性,而非真實性。

各檔案格式涵蓋位元組的起點與終點

不同檔案格式涵蓋的位元組並不相同。兩個正確的實作結果不一致,最常見的原因就是其中一個包含了標頭或長度欄位,而另一個則沒有。下表列出使用 CRC-32/ISO-HDLC 的格式之標準涵蓋範圍。

格式涵蓋的位元組儲存位置
gzip (RFC 1952)未壓縮的原始位元組,於壓縮前計算結尾區,小端序,位於 ISIZE 之前
PNG區塊類型代碼加上區塊資料,適用於每個使用 CRC 的 IDAT 與輔助區塊每個區塊末端的 4 位元組大端序結尾
ZIP 本地檔案標頭從簽章到檔名與延伸欄位之間的位元組,不含資料描述子本地標頭中的 4 位元組小端序欄位
ZIP 中央目錄項目從中央目錄標頭簽章到檔案註解結尾之間的位元組中央目錄項目中的 4 位元組小端序欄位
ZIP 資料描述子選擇性的 4 位元組簽章,接著是 CRC32,再來是壓縮與未壓縮大小當一般用途旗標的第 3 位元被設定時,位於檔案資料之後

在驗證下載的檔案時,請先找出儲存的值,再確認規格所指定的涵蓋位元組,然後只將這些位元組輸入計算機。如需關於 ZIP、PNG 與 gzip 等格式特定位元組範圍的更深入指引,請參閱如何計算 ZIP、PNG 與 gzip 檔案的 CRC32

正確比對 8 位數結果

輸出會格式化為恰好 8 個小寫十六進位數字,且該值會被視為無符號,因此前導零一律會顯示。前導的 0x00 位元組會在輸入時保留,並影響最終的 8 位數輸出,而額外的前導 0x00 位元組也會持續影響結果。因此,刪除前導零或將結果改為大寫,是「幾乎相符」回報中常見的原因。

此計算機使用一個由反射多項式 0xEDB88320 建構成的 256 項表格,從最低有效位元開始處理每個位元組,並在格式化前以 0xFFFFFFFF 對暫存器進行補數運算。這是 RFC 1952 中針對 gzip 所描述的實用查表驅動方法,並與 zlib 檢查碼手冊中記錄的演算法相符。在相同的位元組序列上與 zlib 的 crc32 函式進行交叉比對,是確認差異出在位元組範圍而非演算法的快速方法。

常見的變體與位元組範圍錯誤

數種 32 位元 CRC 公式存在著不同的多項式、初始值或最終 XOR 常數。其區別性參數列示如下。

變體反射多項式初始值最終 XOR「123456789」的檢查值
CRC-32/ISO-HDLC(本工具)0xEDB883200xFFFFFFFF0xFFFFFFFFcbf43926
CRC-32C(Castagnoli)0x82F63B780xFFFFFFFF0xFFFFFFFFe3069283
CRC-32/MPEG-20x04C11DB70x000000000x000000000376E6E7
CRC-32/BZIP20x04C11DB70xFFFFFFFF0xFFFFFFFFFC891918
CRC-32/JAMCRC0xEDB883200xFFFFFFFF0x00000000340BC6D9

若 123456789 的預期值不是 cbf43926,表示來源使用了不同的 32 位元公式。同樣常見的問題還有:將涵蓋的位元組重新輸入為可見文字,因而遺失了 CR LF 與 LF 之間、UTF-8 與 UTF-16 之間、NFC 與 NFD 正規化之間,或原始位元組與其 Base64 表示之間的差異。當協定交給你的是位元組,請貼上位元組;當交給你的是文字,請確認編碼恰好為 UTF-8,沒有 BOM 也沒有經過任何換行字元的正規化轉換。

CRC32 並非安全性或真實性檢查

CRC-32 是一種循環冗餘檢查,設計用於偵測資料中常見的偶發變更,例如不穩定磁碟上的位元翻轉或下載被截斷。它具有線性特性且極易被操控:任何想要讓承載資料的雜湊值符合所選 32 位元值的人,都可以在不知道原始資料的情況下構造出來。CRC32 既不是加密、也不是密碼雜湊、訊息驗證碼,更不是數位簽章。

它的用途在於確認你解壓縮出來的封存檔與旁邊公布的數值一致,或是確認寫入磁碟的檔案仍與記憶體中的內容相符。請勿將它用於驗證不受信任的軟體、授權指令、保護憑證,或是用於證明檔案來自可信的發行者。若需對抗性環境下的完整性保護,請透過經過驗證的管道傳輸檔案,並同時公布 SHA-256 或更強的密碼學摘要。

檔案大小限制與處理較大檔案的作法

瀏覽器工具最多可處理 5,000,000 位元組的輸入,以確保查表驅動迴圈在頁面上仍能保持回應速度。輸出絕不會被靜默截斷:永遠會顯示 8 個十六進位數字,且該值被視為無符號,因此任何被接受輸入的結果都是完整的 32 位元檢查值。空白的程式化輸入其 CRC 為 00000000,雖然介面會要求輸入資料以避免不小心按到空白鍵時,看起來像是進行了一次有意義的驗證。

若承載資料較大,請將輸入切割為不超過上限的區塊,分別計算每個區塊自身位元組的 CRC32,然後利用該演算法的串流特性將各區塊的值合併起來。若下游消費者已提供參考值,建議優先選擇能直接從磁碟讀取檔案或以串流方式讀取的工具,這樣整個檔案就能在不需手動分塊的情況下一次完成雜湊運算。