一個 CRC32 計算器的替代方案應該實作標準的 CRC-32/ISO-HDLC 變體,也就是對位元組 1、2、3、4、5、6、7、8、9(ASCII)會產生眾所周知的檢查值 cbf43926 的公式,而 ZIP、gzip 與 Ethernet 都使用它來標記意外損毀。基於瀏覽器的 CRC32 計算器 完全遵循該變體:寬度 32、反射多項式 0xEDB88320、初始暫存器 0xFFFFFFFF、反射位元組處理,以及最終 XOR 0xFFFFFFFF,接著將補數格式化為八位數的小寫十六進位字串。由於計算完全在頁面中進行,輸入永遠不會傳送到伺服器,而複製動作只會回傳精確的 32 位元值,不帶任何裝飾。嚴格的參數、透明的位元組處理,以及僅限本機的處理程序,這三者的結合正是嚴謹的 CRC32 替代方案與那些在變體、編碼或輸出格式上悄悄不一致的眾多頁面之間的分野。當兩個計算器對同一字串回傳不同的八位數結果時,原因幾乎總是參數不符、編碼選擇不同,或是位元組範圍不同,而不是任一引擎的錯誤。

何時該使用不同的 CRC32 工具
並非每個 CRC32 工具都值得信賴。搜尋結果中充斥著隨意掛上「CRC32」標籤、接收文字後回傳某八個字元的字串,卻不揭露其使用的多項式、初始值、最終 XOR 或位元組序列的頁面。其中有幾個甚至無法通過標準檢查:輸入 123456789 的 ASCII 位元組時,ISO-HDLC 變體應輸出 cbf43926。若結果不符,該工具便是在實作另一種 CRC,可能是 CRC-32C、MPEG-2、BZIP2 或 JAMCRC,卻仍自稱 CRC32。
一個真正的替代方案必須讓三項承諾清楚可見。第一,變體必須事先標明並附上參數,而非從輸出反推。第二,輸入編碼必須明確無歧義,以便在貼上 UTF-8 文字的使用者能在規格定義涵蓋範圍時切換到精確的十六進位位元組。第三,結果必須可重現:再次餵入相同的位元組,每次都會得到相同的八位數,包括短輸入的前導零。若想更深入了解變體選擇與位元組邊界,請參考逐步指南:挑選正確的 CRC32 變體與位元組。
正確的替代方案必須做對的事
一個值得信賴的 CRC32 替代方案在四個軸向上與眾不同。第一是參數透明度。CRC-32/ISO-HDLC 這個被 gzip、ZIP、PNG 與大多數 Ethernet 訊框使用的變體,有一套固定的配方:寬度 32、反射多項式 0xEDB88320、初始值 0xFFFFFFFF、反射輸入處理、最終 XOR 0xFFFFFFFF,以及對 123456789 的 ASCII 位元組的標準檢查值 cbf43926。不公開這些參數的工具無法被稽核,使用者也無從得知所計算的究竟是 cbf43926,還是某個經過位移、交換或重新命名的變體。
第二個軸向是位元組的清晰度。UTF-8 文字與明確的十六進位位元組對一般使用者而言看似可互換,但只要字串中含有帶腔調字母、CJK 字元、表情符號或任何 ASCII 無法表示的位元組,兩者便會產生不同的 CRC 值。第三是輸出規範:一個無正負號的 32 位元值,一律呈現為剛好八個小寫十六進位數字,不可修剪前導零,也不進行有號整數的正負號轉換。下表彙整了常見的 CRC32 公式以及它們與 ISO-HDLC 基準的偏差。
| 變體 | 反射多項式 | 初始值 | 最終 XOR | 123456789 的檢查值 | 常見用途 |
|---|---|---|---|---|---|
| CRC-32/ISO-HDLC | 0xEDB88320 | 0xFFFFFFFF | 0xFFFFFFFF | cbf43926 | gzip、ZIP、PNG、Ethernet |
| CRC-32C(Castagnoli) | 0x82F63B78 | 0xFFFFFFFF | 0xFFFFFFFF | e3069283 | iSCSI、SCTP、ext4、BTRFS |
| CRC-32/MPEG-2 | 0x04C11DB7 | 0xFFFFFFFF | 0x00000000 | 0376e6e7 | MPEG-2、AVI |
| CRC-32/BZIP2 | 0x04C11DB7 | 0xFFFFFFFF | 0xFFFFFFFF | 19a36f8c | bzip2 |
| CRC-32/JAMCRC | 0xEDB88320 | 0xFFFFFFFF | 0x00000000 | 340bc6d9 | JAM、部分舊式工具 |
空輸入會得到 00000000,這是數種變體共同產生的結果,因此它本身無法識別是哪個公式。標準的數值檢查 cbf43926 則能將 CRC-32/ISO-HDLC 與其他 32 位元公式區分開來,而公開的參數能進一步確認其吻合。任何公開參數不符合第一列,但對 123456789 的檢查值也不等於 cbf43926 的工具,所實作的便是另一個公式。CRC32 計算器僅涵蓋 CRC-32/ISO-HDLC,並在介面中聲明此範圍。若您的目標格式需要的是 CRC-32C、MPEG-2、BZIP2 或 JAMCRC,則需要使用其他工具。
如何在這個瀏覽器工具中計算步驟
- 確認變體與位元組範圍。 在開啟任何工具之前,請先閱讀您要驗證的格式規格(gzip、ZIP、PNG、嵌入式韌體區塊、自訂通訊協定)。確認它明確指定 CRC-32/ISO-HDLC,並確認您知道涵蓋哪些位元組。許多格式會將檔頭、長度欄位或儲存的檢查碼欄位排除在 CRC 之外;這些邊界與變體本身同樣重要。
- 選擇正確的輸入模式。 只有在格式明確指出涵蓋區域為 UTF-8 字串時,才使用 UTF-8 文字模式。若格式給定的是精確位元組(例如從封包擷取到的十六進位傾印、從磁碟還原的承載資料,或任何以位元組序列為準的內容),請切換到十六進位模式。在十六進位模式下,貼上以空白分隔的位元組對,總位數必須為偶數,且不得包含 0x 前綴或註解。工具會移除位元組對之間的空白,但除此之外仍要求十六進位數字的總數為偶數。
- 執行計算並讀取八位數字。 送出輸入後,複製八位數的小寫十六進位結果。空輸入會得到 00000000;標準的數值 ASCII 檢查則會得到 cbf43926。前導零很重要:值 1a2b3c 會顯示為 001a2b3c,帶有兩個前導零,因為該欄位是固定寬度,且該值被視為無正負號。
- 與預期值進行比對。 依序比對全部八個數字,看是否與格式規格、嵌入式標頭或您信賴的文件中所發布的值相符。單一數字不符通常代表變體、位元組範圍或編碼有誤,而非工具運作異常。
- 將相符視為意外錯誤的證據,而非真實性的證明。 CRC32 的相符僅能證明位元組未遭受該多項式設計要偵測的那類損毀。面對惡意竄改、軟體下載驗證、韌體信任,或任何攻擊者可以挑選位元組的情境,請改用如 SHA-256 之類的加密摘要,並搭配經驗證的發佈管道。
在 UTF-8 文字與十六進位位元組之間抉擇
文字模式很方便,但只有在目標格式所期待的正好是 UTF-8 時才適用。介面在處理前會將字串編碼為 UTF-8,因此一個 ASCII 字元佔一個位元組、一個帶腔調字母佔兩個位元組、一個 CJK 字元佔三個位元組、一個表情符號佔四個位元組。一個處理 UTF-16 碼元、舊式字碼頁、Unicode 標準化形式或不同換行慣例的工具,即使自稱「CRC32」,也會對同一可見字串回傳不同的 CRC。如有疑慮,請切換到十六進位模式,直接貼上位元組序列。
十六進位模式更嚴格也更誠實:位元組對之間的空白會被移除;0x 之類的前綴會被拒絕;非空白的分隔符會被拒絕;註解會被拒絕;尾端奇數的半位元組也會被拒絕。前導 00 位元組會被保留並影響結果;當位元組範圍包含以零填補的資料,而以文字重新輸入會靜默地將其省略時,這點格外重要。輸出僅針對實際提供的位元組進行計算,而非依據所鍵入的字元——這是當規格明確給定位元組序列時唯一安全的行為。
限制、邊界,以及 CRC32 不做的事
此實作接受最多 5,000,000 位元組的輸入;超出此範圍的輸入會被拒絕,以維持查表驅動迴圈的反應速度。輸出絕不會被靜默截斷,數值會被視為無正負號,且一律顯示八個十六進位數字。Python zlib 的交叉檢查會驗證多位元組 UTF-8 的邊界;另有八組外部檢查字串涵蓋空輸入、短訊息、常見的訊息摘要與字母組套件、標準數值檢查,以及 quick-brown-fox 句子。這些值的存在是為了證明所宣告的變體與位元組處理方式,而不僅僅是證明某個編碼器與其解碼器彼此一致。
CRC-32 不是加密、不是加密雜湊、不是訊息驗證碼,也不是數位簽章。它具有線性且極易被竄改:給定任何想要的四位元組輸出,攻擊者都能構造出產生該輸出的輸入。請勿使用 CRC32 來驗證不受信任的軟體、授權指令、保護憑證,或證明某個檔案來自可信的發行者。RFC 1952 與 zlib checksum 手冊 中的標準指引皆將該值視為用於偵測意外損毀的非加密完整性標記——這也正是此多項式被設計來偵測的目標。
若想進一步了解,請參考在瀏覽器中執行的密碼產生器替代方案。