在電腦網路中,總和檢查碼(checksum)是一個附加在訊框(frame)或區段(segment)上的短數值,可讓接收端偵測資料在傳輸過程中是否意外產生位元錯誤。發送端在一段定義明確的位元組範圍上計算總和檢查碼,將其附加在訊息後傳送,而接收端則在相同的位元組上重新計算;若兩者數值不一致,該封包便會被視為已損毀。實際上「checksum」一詞並非指單一演算法:IP、TCP 與 UDP 使用的是 16 位元的網際網路總和檢查碼,工業匯流排則常使用 Modbus ASCII 縱向冗餘檢查(LRC)或 XOR-8 區塊檢查字元(BCC),儲存系統則倚賴循環冗餘檢查(CRC),例如 CRC-32。由於公式與位元組範圍同樣重要,因此若給出一個籠統的「如何計算電腦網路中的總和檢查碼」答案,往往會誤導使用者。「Checksum Calculator」鎖定在規模較小、定義明確的一位元組情境:它會根據您輸入的確切位元組,輸出明確的 XOR-8 BCC、Modbus ASCII 二補數 LRC,以及原始加總模數 256 的值,並在結果旁邊顯示位元組數量。所有運算都在本機端執行,因此您可以從封包擷取結果貼上一段位元組序列,將三種輸出與廠商手冊比對,再判斷您的裝置究竟預期使用哪一種。

how to calculate checksum in computer networks
how to calculate checksum in computer networks

總和檢查碼在電腦網路中的作用

在電腦網路中,總和檢查碼是一個附加在訊框或區段上的小型數值標記,用來協助接收端找出在傳輸過程中混入的位元錯誤。在鏈結層中,這個標記是根據表頭(header)、酬載(payload)或兩者所產生;在傳輸層中,它通常涵蓋該區段的表頭加上酬載,並且會在每一個會變動表頭的節點重新計算。

其機制相當單純。發送端在一段固定的位元組範圍上執行一組確定性的公式以產生一個短數值,將它作為訊框的一部分加以傳送,而接收端則在相同的位元組上執行同一公式。若兩端得到相同的數字,該訊框即視為通過;若不一致,則將訊框捨棄,並在可靠(reliable)協定中觸發重傳。任何總和檢查碼都無法偵測出所有可能的損毀,但設計良好的機制能在其偵測寬度內捕捉到所有單位元錯誤以及大多數的叢發錯誤(burst error)。

公式的實際內容因協定而異。IPv4、TCP 與 UDP 所使用的網際網路總和檢查碼,是對 16 位元字組進行 16 位元一的補數加總。以太網訊框使用的是 32 位元的 CRC。Modbus ASCII 則定義了對訊息位元組進行的 8 位元二的補數 LRC。許多序列裝置使用 8 位元的 XOR 區塊檢查字元,有時會標示為 BCC。這些彼此並不能互換:Modbus LRC 永遠不會等於 CRC-32,而 XOR-8 BCC 也無法驗證 IP 表頭。選擇正確的演算法,應從閱讀協定規格書開始,而非從工具開始。

為何單一演算法無法適用於所有協定

「Checksum」一詞在業界被廣泛且鬆散地使用,這也是為何不同的教學文件之間常出現矛盾。三份協定文件都可能使用 checksum 這個詞,卻分別指涉三種不同的公式。同樣的問題也出現在區塊檢查字元(BCC)與縱向冗餘檢查(LRC):某家廠商的 BCC 可能是加法總和、XOR 或 CRC,端看產品線而定。

具體而言,不同演算法的輸入與轉換方式會在以下幾個維度上有所不同:

  • 初始值:XOR-8 與 Modbus ASCII LRC 為 0,某些網際網路與 CRC 變體則為非 0。
  • 位元寬度:依協定而定,可為 8 位元、16 位元或 32 位元。
  • 位元組範圍:僅表頭、僅酬載、表頭加酬載,或是明確的訊框欄位(並排除框定字元)。
  • 最終轉換:原始值、一的補數、二的補數、位元組反序,或高位元組先傳。

只要上述任何一個維度錯誤,接收端就會拒絕合法的訊框,或接受已損毀的訊框。Checksum Calculator 透過在您輸入的確切位元組上計算三種具名、單位元組的公式,來迴避這種模糊性。它不會替您挑選,而是將標示清楚的結果攤開,讓您得以將公式對應到規格書。

Checksum Calculator 所計算的三種演算法

此計算工具會對同一段輸入位元組序列執行三次計算,並輸出三個標示清楚的十六進位值,每個值都是剛好兩個小寫十六進位數字,並在旁邊附上輸入的位元組數量。頁面最多處理 500,000 位元組,絕不會默默截斷輸入,且若遇到格式錯誤的十六進位資料也不會輸出部分結果。

XOR-8 區塊檢查字元從 0 開始,將每個位元組 XOR 進一個 8 位元的累加器。由於 XOR 具有交換性,位元組順序並不影響結果,且不會產生進位。其行為與 BALTECH XOR-8 BCC 參考文件中所描述的 8 位元 XOR 一致。部分序列與裝置協定會將這個值作為一個尾端位元組傳輸,並標示為 BCC,但也有其他廠商將 BCC 一詞借用於加法總和或 CRC。請在使用前加以確認。

Modbus ASCII 縱向冗餘檢查會將所有訊息位元組加總進一個 8 位元的欄位,丟棄超過位元 7 以外的進位,再取最終加總結果的二補數。等同地,LRC 即為位元組加總的負值模數 256。官方的「Modbus over serial line」規格書明確指出,傳入 LRC 計算的位元組並不包含起始冒號字元與結尾的 CRLF。

模數 256 的加總就是二補數步驟之前,一般位元組加總的低八位元。它以診斷性的中間結果呈現。由於加總與 LRC 在模數 256 下加起來為 0,因此同時比較兩者,有助於判斷廠商手冊實際預期的形式。

演算法公式初始值最後步驟典型框定方式
XOR-8 BCC將每個位元組 XOR 進一個 8 位元累加器0x00選取的酬載位元組
Modbus ASCII LRC加總位元組,保留低 8 位元0x00二補數僅訊息位元組,排除冒號與 CRLF
模數 256 加總加總位元組,保留低 8 位元0x00診斷用,無框定規則

若您的協定需要的是 CRC-16、CRC-32、Fletcher、Adler、16 位元網際網路總和檢查碼,或任何密碼學雜湊,則本工具並不適用。請改用能對應到目標寬度與多項式的計算工具。

如何逐步計算總和檢查碼

  1. 依據協定的參考手冊,明確找出總和檢查碼所涵蓋的位元組範圍:僅表頭、僅酬載、表頭加酬載,或是某個特定子集。同時留意是否包含或排除框定字元,例如 Modbus 的起始冒號或結尾的 CRLF。
  2. 將這些位元組轉換成工具可接受的輸入表示方式。若裝置傳輸的是可列印的 ASCII 十六進位字元,請將輸入模式切換為十六進位,並以每個位元組剛好兩個十六進位數字的方式輸入,數字間可選擇性地加上空白。若裝置傳輸的是原始位元組,請在文字模式下貼上相同的字元,瀏覽器會先將該字串以 UTF-8 編碼;非 ASCII 字元此時會各佔好幾個位元組,因此顯示的位元組數量可能會大於可見的字元數。
  3. 依照步驟 1 的定義,將位元組序列準確地貼入 Checksum Calculator。格式錯誤的十六進位(例如奇數長度的半位元組、0x 之類的前綴、逗號、連字號或註解)會被拒絕而非猜測處理,因此輸入前請先清理乾淨。
  4. 執行計算。頁面會輸出三個標示清楚的十六進位值:XOR-8 BCC、Modbus ASCII LRC,以及模數 256 加總,外加實際處理的位元組數量;不會默默截斷,且上限為 500,000 位元組。
  5. 將三個標示清楚的結果與裝置說明文件比對,並複製相符的那一個。複製出來的內容包含標籤、三個數值與位元組數量,因此貼上的診斷註記仍會保留所選的解讀。
  6. 在將結果用於實際流量之前,請以廠商提供的已知測試向量(例如 Modbus ASCII 的 123456789 範例)進行驗證。

實作範例:驗證五位元組訊框的 Modbus ASCII LRC

以十六進位位元組 01 02 03 04 05 為例,這是開發人員在偵錯序列裝置時常會貼上來的一種短訊框。Modbus ASCII LRC 會將這些位元組加總進一個 8 位元的欄位,丟棄進位,再回傳其二補數。

位元組加總:0x01 + 0x02 + 0x03 + 0x04 + 0x05 = 0x0F。由於該值已小於 256,因此不會丟棄任何進位。0x0F 的二補數為其位元反轉後再加一:~0x0F = 0xF0,加一後為 0xF1。預期的 LRC 即為 0xF1。

驗證其關係:0x0F + 0xF1 = 0x100,在模數 256 之下同餘於 0,確認加總與 LRC 如 Modbus 規格所要求地彼此對消。

作為對照,同樣的五個位元組所產生的 XOR-8 BCC 為 0x01,模數 256 加總為 0x0F。手動逐步走一次 XOR:0x01 ^ 0x02 = 0x03;0x03 ^ 0x03 = 0x00;0x00 ^ 0x04 = 0x04;0x04 ^ 0x05 = 0x01。將這五個位元組以十六進位模式貼入計算工具,頁面會輸出 XOR-8 BCC 為 01、Modbus ASCII LRC 為 f1、診斷加總為 0f,並顯示位元組數量為 5。

單位元組總和檢查碼的限制(以及何時應改用其他方法)

單位元組的總和檢查碼能偵測到一部分的意外變動,但它們並非密碼學雜湊函數、訊息鑑別碼、數位簽章,也無法證明來源。XOR 與加法總和都有大量碰撞:微小的訊息編輯可能讓數值保持不變,而攻擊者亦可刻意建構出產生相同標記的不同酬載。

只有在協定確實預期使用 8 位元 BCC、Modbus ASCII LRC,或模數 256 的加法總和時,才適合使用本計算工具。凡涉及身分憑證、命令授權、軟體下載,或對抗惡意網路流量的身分驗證,請採用該協定實際要求的安全機制。若裝置手冊提及 CRC-16、CRC-32、Fletcher、Adler、網際網路總和檢查碼,或具名的雜湊(例如 SHA-256),請改用具備該精確演算法的工具,切勿以單位元組加總替代。

在使用計算工具時,有兩項操作性限制值得注意。首先,頁面最多處理 500,000 位元組,且絕不會默默截斷輸入,因此貼上過大的內容會清楚回報錯誤,而非產生誤導性的部分結果。其次,在十六進位模式下,解析器會拒絕格式錯誤的輸入而非猜測處理,因此奇數長度的半位元組、散落的 0x 前綴與散落的逗號,需在提交前先清理乾淨。

作為參考,Modbus 公式遵循官方的「Modbus over serial line」規格書,而 XOR-8 BCC 的行為也已與明確定義對選定位元組進行 8 位元 XOR 的廠商文件交叉比對。Modbus 的 123456789 ASCII 測試向量是用來驗證本實作的外部測試樣本之一。

若您正在權衡各種方案,Calculate the Checksum for a FIX Message 一文對此有詳細說明。

若您正在權衡各種方案,Calculate the SHA-1 Hash of a File and Match a Checksum 一文對此有詳細說明。