Modbus RTU 訊框使用的是 CRC-16/MODBUS,這是一種 16 位元的循環冗餘校驗,反射多項式為 0xA001、初始暫存器為 0xFFFF、沒有最終 XOR;Modbus ASCII 訊框則用一個位元組的 LRC,取代這個兩位元組的 CRC。 這個底層線路層級的事實,正是「calculate CRC for Modbus」這個搜尋詞背後的關鍵,也是人們找錯計算工具的第一個原因:內建在 gzip、ZIP、PNG 與 zlib 中、廣泛使用的 CRC-32/ISO-HDLC 公式,是一套完全不同的演算法,有著不同的位元寬度、不同的多項式、不同的初始暫存器,以及不同的最終 XOR——因此把一個 Modbus RTU 訊框餵進一個 CRC-32 工具,不可能算出從機在訊框結尾預期看到的那個兩位元組數值。這篇指南會逐一並排比對確切的參數差異,說明本站的CRC32 Calculator 如何處理它原本就是為之打造的 CRC-32/ISO-HDLC 變體,並在線路上傳輸的位元組真的是 Modbus RTU 或 Modbus ASCII 時,指引你找到正確的工具。

Modbus CRC-16 與 CRC-32/ISO-HDLC:真正的差異
「Modbus 用的 CRC」這個說法,幾乎都是指附加在每個 Modbus RTU 訊框結尾的 16 位元 CRC。這個 CRC 的計算方式是:位元寬度 16、反射多項式 0xA001(0x8005 的位元反轉形式)、初始暫存器 0xFFFF、輸入與輸出都做反射處理、沒有最終 XOR——這些正是被歸類為 CRC-16/MODBUS 這個變體的參數。Modbus ASCII 是較舊、可列印的變體,它用一個位元組的 LRC,取代那個兩位元組的 CRC:也就是 ASCII 承載資料中每個位元組總和的二補數,不含冒號與結尾的 CRLF。
這個頁面上的 CRC32 Calculator,兩者都沒有實作。它實作的是 CRC-32/ISO-HDLC:位元寬度 32、反射多項式 0xEDB88320、初始暫存器 0xFFFFFFFF、位元組以反射方式處理,以及最終 XOR 0xFFFFFFFF。這正是 gzip 成員標準化採用的變體,也是 zlib 文件中記載用於其校驗和的公式,同時內建在 ZIP 封存檔與 PNG 區塊中。把一個 Modbus RTU 訊框跑過這個工具,會得到一個有效的 CRC-32,只是不是你的從機所預期的那個 CRC。
| 參數 | CRC-16/MODBUS | CRC-32/ISO-HDLC |
|---|---|---|
| 位元寬度 | 16 位元 | 32 位元 |
| 反射多項式 | 0xA001 | 0xEDB88320 |
| 初始暫存器 | 0xFFFF | 0xFFFFFFFF |
| 最終 XOR | 0x0000 | 0xFFFFFFFF |
| 典型輸出長度 | 4 個十六進位數字 | 8 個十六進位數字 |
| 使用場合 | Modbus RTU 訊框 | gzip、ZIP、PNG、zlib |
當你的 Modbus 主機或從機拒絕某個訊框時,不對盤的原因幾乎都是三者之一:算的是錯誤的變體、涵蓋的位元組範圍不對(有些通訊協定堆疊會納入或排除位址位元組),或是位元組被重新輸入,而不是依照傳輸時的原樣貼上。
CRC32 Calculator 實際實作的內容
區分 CRC-32/ISO-HDLC 與其他數十種 32 位元公式的每一項參數,都被鎖定在這個工具中:位元寬度 32。反射多項式 0xEDB88320。初始暫存器 0xFFFFFFFF。位元組處理順序為最低有效位元優先。最終 XOR 0xFFFFFFFF。這套演算法會從反射多項式建立一張 256 筆項目的表格,把每個輸入位元組與暫存器的低位元組做 XOR,查出對應的表格餘數,再與向右移八位元後的暫存器合併。暫存器在最後會被取補數,並補上前導零,格式化成八位數的小寫十六進位字元。
標準檢查值是字串「123456789」的 ASCII 位元組(九個位元組,0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39),應該要算出cbf43926。這個值是RFC 1952 以及 CRC32 Calculator 自我檢查套件中的標準參考值。如果某個工具對同樣九個位元組給出不同的八位數答案,代表變體或位元組編碼方式不同——最常見的情況是位元組被編碼成 UTF-16 碼元、換行符號被正規化了,或是使用了 MPEG-2 與 BZIP2 所用、未反射的 0x04C11DB7 多項式。
文字模式把輸入當成一個 UTF-8 字串處理。ASCII 字元各佔一個位元組;帶重音的拉丁字母通常佔兩個位元組;中日韓文字與表情符號則佔三或四個位元組。十六進位模式完全略過編碼處理,接受偶數個十六進位數字,可選擇以空白分隔,每兩個數字組成一個位元組。像 0x 這樣的前綴、空白以外的分隔符號、註解,以及多出來的半位元組尾巴,都會被拒絕,以免不小心混入的雜訊靜默地改變結果。
如何用 CRC32 Calculator 計算 CRC-32
這個頁面上的操作流程,對應到經過驗證的操作步驟,並讓從輸入到輸出的路徑保持簡短。
- 確認變體。 打開你要對照驗證的規格或原始碼——gzip 成員尾端、ZIP 中央目錄記錄、PNG IDAT 區塊——確認它要求的是 CRC-32/ISO-HDLC,而不是 CRC-32C、MPEG-2、BZIP2 或 JAMCRC。對「123456789」這九個 ASCII 位元組的檢查值,必須等於 cbf43926。
- 選擇正確的輸入模式。 只有當規格明確指名 UTF-8、而且承載資料真的是字元資料時,才選擇 UTF-8 文字模式。當規格給你的是確切的位元組——一份訊框傾印、一個檔案標頭的十六進位檢視、一個可能以 00 開頭的區塊——請直接把這些位元組貼進十六進位模式,而不要重新輸入。
- 輸入確切的承載資料。 在文字模式下,逐字輸入或貼上字串,留意行結尾與尾端空白。在十六進位模式下,貼上一串連續或以空白分隔、位數為偶數的十六進位字串;這個工具會去除空白,但會保留每一組位元組,包括開頭的 00。
- 計算並讀取完整的八位數字。 結果永遠是八個小寫十六進位數字,前導零也會顯示出來。空的程式化輸入會產生 00000000,但可見的介面會要求輸入資料,以免不小心的空白點擊,看起來像是一次有意義的驗證。
- 比對全部八個數字。 相符只能確認針對所宣告的變體與位元組範圍,結果在意外錯誤上的一致性。複製這個確切的 32 位元值——複製動作只會把這八個十六進位字元放進剪貼簿,不會有其他內容。
- 判斷 CRC 是否足夠。 如果威脅模型中包含惡意竄改,CRC 相符並不等於身分驗證。請改用經過信任通道傳輸的密碼學摘要。
針對 Modbus 訊框,該改用什麼
對於真正的 Modbus 流量,合適的工具取決於線路格式。Modbus RTU 需要 CRC-16/MODBUS:位元寬度 16、反射多項式 0xA001、初始值 0xFFFF、沒有最終 XOR、輸出時低位元組在前。本站的Checksum Calculator 涵蓋了 Modbus ASCII 那一側,提供明確的二補數 LRC 運算,在你排錯 ASCII 訊框流量,或處理在兩者之間轉換的閘道器時很有用。如果只有 CRC32 Calculator 可用,請把每一個 Modbus 位元組配對貼進十六進位模式,並先確認變體——但要有心理準備,這個八位數的 ISO-HDLC 值會被 Modbus 通訊協定堆疊拒絕,因為多項式與位元寬度根本對不上。
想更深入了解 Modbus LRC 的做法,How to Calculate Checksum: XOR-8 and Modbus LRC 這篇指南用具體的十六進位範例,說明了位元組加總與二補數運算,當你的專案是 ASCII 訊框時,這是合適的延伸閱讀。
| 線路格式 | 完整性欄位 | 演算法 | 該用的工具 |
|---|---|---|---|
| Modbus RTU | 2 位元組 CRC,低位元組在前 | CRC-16/MODBUS | 專用的 CRC-16/MODBUS 計算工具(不在本頁) |
| Modbus ASCII | 1 位元組 LRC | 位元組總和的二補數 | Checksum Calculator |
| gzip / ZIP / PNG | 4 位元組 CRC-32,低位元組在前 | CRC-32/ISO-HDLC | CRC32 Calculator |
需要留意的限制與驗證
CRC32 Calculator 強制設下 5,000,000 位元組的輸入上限,讓這套依賴查表的掃描在瀏覽器中維持回應速度。計算在本機執行;承載資料永遠不會被上傳,而複製動作只會複製那八位數的確切數值,不含周圍的標籤文字。輸出結果被當成一個不帶正負號的 32 位元整數處理,永遠不會被靜默截斷,因此即使結果剛好很小,也仍然會顯示全部八個十六進位數字,以及區分它與較短字串所需的前導零。若要在整個系列中挑選正確的變體,文章How to Find CRC32: Pick the Right Variant and Bytes 是站內最貼近的延伸閱讀。
有八組外部檢查字串會針對這套實作執行測試:空輸入、短訊息、常見的訊息摘要與字母組合套件、對「123456789」的標準數值檢查,以及那句經典的敏捷棕狐句子。一項 Python zlib 交叉驗證,涵蓋了多位元組 UTF-8 的邊界情況。這些檢查驗證的是所宣告的變體與位元組處理方式,而不只是確認某個編碼器與它自己的解碼器互相一致。
什麼時候光是 CRC 相符還不夠
CRC-32 是一種循環冗餘校驗,設計目的是抓出儲存或傳輸資料中常見的意外變化——位元翻轉、檔案被截斷、複製錯誤。它是線性的,而且很容易被刻意操弄。CRC-32 相符,不是加密,不是密碼學雜湊,不是訊息驗證碼,不是數位簽章,也不能證明來源。請不要用它來驗證不受信任的軟體、授權 Modbus 指令、保護憑證,或宣稱某個檔案來自受信任的發佈者。
對於對抗性的完整性需求——也就是可能有惡意行為者想偽造或竄改位元組的情況——請在一條受信任的散布路徑上,搭配使用密碼學摘要(SHA-256 或更強),或使用像 HMAC-SHA-256 這樣經過驗證的基本演算法。請只把 CRC 相符當成意外錯誤一致性的證據,絕不要當成安全性上的真實性證明。