XOR-8 區塊檢查字元 (BCC) 是所選範圍內每個位元組的累積 XOR,存放在一個從 0x00 開始且永遠不會產生進位的 8 位元累加器中。由於 XOR 符合交換律,位元組的順序並不影響結果;結果只取決於涵蓋位元組的多重集。那個單一位元組的結果就是大多數設備手冊標示為「BCC」的值,雖然相同的標籤有時也用於加法總和檢查碼、LRC、CRC,或是針對訊框不同部分的檢查碼。為了明確區分,速查表必須清楚寫出公式、涵蓋的位元組、寬度,以及任何最終的轉換步驟。XOR-8 BCC、原始總和模數 256,以及 Modbus ASCII 二補數 LRC 這三者都輸出 8 位元,但在最後一步有所不同:XOR-8 不變動累加器,原始總和會截斷進位,而 Modbus LRC 則是先截斷進位再取二補數。將它們視為可互換的值,是「BCC」欄位被裝置拒絕最常見的原因。

這三個 8 位元值實際上是什麼
一份實用的 BCC 檢查碼速查表必須清楚區分三個常見的 8 位元公式,因為每一個都對同一段位元組序列回答略為不同的問題。XOR-8 BCC 問的是「哪一個單一位元組能捕捉輸入的同位元模式?」總和模數 256 問的是「一般算術總和的低位元組是什麼?」Modbus ASCII LRC 問的是「附加在輸入之後,哪一個單一位元組能讓總和的低位元組變成零?」下表中每一列描述其中一個公式,不省略任何步驟。
| 屬性 | XOR-8 BCC | 總和模數 256 | Modbus ASCII LRC |
|---|---|---|---|
| 初始值 | 0x00 | 0x00 | 0x00 |
| 每個位元組的運算 | XOR 進累加器 | 加進累加器 | 加進累加器 |
| 進位行為 | 不會發生進位 | 捨棄第 7 位元之後的進位 | 捨棄第 7 位元之後的進位 |
| 最終轉換 | 無 | 無 | 二補數 |
| 結果寬度 | 8 位元 | 8 位元 | 8 位元 |
| 輸出格式 | 兩個小寫十六進位數字 | 兩個小寫十六進位數字 | 兩個小寫十六進位數字 |
Modbus ASCII LRC 是總和模數 256 的負值,所以總和與 LRC 在模數 256 下相加永遠為零。並排顯示兩者是刻意的診斷選擇:如果廠商文件寫「檢查碼等於位元組的總和」,那麼答案就是總和模數 256 那一欄;如果寫「LRC」或「縱向冗餘檢查」,那麼答案就是 LRC 那一欄;如果只寫「BCC」而沒有進一步說明,則必須先確認手冊描述的是 XOR 還是加法,才能決定該相信哪一欄。
如何逐步計算 BCC 檢查碼
要驗證手冊中的「BCC」範例是否與你自己的程式碼一致,最快的方法就是用明確的公式在本地端算出相同的值。檢查碼計算機重現了本速查表中的三個公式,並回報它實際處理的位元組數,這讓你能確認自己輸入的是正確的位元組範圍,而不是憑空猜測。
- 選擇輸入表示方式。當手冊將訊息列為一串兩位數十六進位值(例如 01 03 00 00 00 0A)時,使用十六進位位元組模式。當手冊將訊息顯示為可列印的 ASCII 字串時,請使用 UTF-8 文字模式。瀏覽器一律先以 UTF-8 編碼文字,因此單一非 ASCII 字元可能會貢獻好幾個位元組到計數中。
- 只輸入檢查碼涵蓋的位元組。如果協定排除了起始冒號或結尾的 CRLF,就只輸入酬載位元組。計算機不會幫你去除框線,它會把你輸入的任何內容視為必須處理的位元組範圍。
- 執行計算。頁面會顯示它處理的位元組數,並顯示三個標示好的兩字元十六進位結果:XOR-8 BCC、總和模數 256,以及 Modbus ASCII LRC。
- 將結果與手冊的計算範例做比對。如果手冊寫的是「BCC」並提供計算範例,請在信任其他答案之前,先在本地端重新計算同一個範例。如果廠商將 BCC 描述為加法而非 XOR,那麼要比對的值就是總和模數 256 那一欄。
- 複製標示好的區塊。複製輸出會保留所有標、三個值以及位元組數,因此貼上的筆記仍能記錄所使用的是哪一種解讀方式。
應包含與排除的位元組
檢查碼不符的最大單一原因就是位元組邊界錯誤。不同手冊畫出的界線位置也不同。Modbus over Serial Line 規範在送入 LRC 的位元組中排除了 ASCII 起始冒號 (:) 與結尾的 CR LF,只有位址、功能與資料欄位本身會被加總。BALTECH 對 8 位元 BCC XOR 的參考說明定義了相同的從零開始的 XOR 行為,套用於選定的位元組;確切的位元組範圍取決於特定的協定或裝置。其他廠商則可能包含前置的長度位元組、從標頭欄位加總到結束符,或定義一個涵蓋兩個標記之間所有內容的獨立「檢查碼」。在使用任何速查表上的值之前,請先在協定文件中找到確切的位元組範圍,並只重新輸入那些位元組。
在十六進位模式下,計算機會拒絕 0x、逗號、冒號、破折號等前置符號,也會拒絕任何不是剛好兩位十六進位數字的位元組。這種嚴格的解析方式能在貼上的訊框格式錯誤時避免默默猜測。在文字模式下,計算機會回報它處理的 UTF-8 位元組數,當訊息包含重音字母或 CJK 字元時,這個數字可能會超過可見的字元數。超過頁面上 500,000 位元組上限的輸入並不會被默默截斷;計算機會回報輸入格式錯誤,而不是產生部分值。
計算範例:01 02 03 04 的 XOR-8 BCC
為了實際觀察公式運作,取四個位元組:0x01、0x02、0x03 與 0x04。XOR-8 BCC 從 0x00 開始,一次一個位元組逐步折疊進累加器:
0x00 XOR 0x01 = 0x010x01 XOR 0x02 = 0x030x03 XOR 0x03 = 0x000x00 XOR 0x04 = 0x04
因此 XOR-8 BCC 為 0x04。同樣四個位元組的總和模數 256 為 0x01 + 0x02 + 0x03 + 0x04 = 0x0A。Modbus ASCII LRC,也就是 0x0A 的二補數,是 0xF6。作為快速交叉驗證,0x0A + 0xF6 = 0x100,其低位元組為 0x00,證實總和與 LRC 在模數 256 下相加為零。對於其他酬載,請對檢查碼計算機執行同樣三行運算,並在送至線路上之前,逐一比對手冊驗證每個結果。XOR-8 結果也可以與 BALTECH 的8 位元 BCC 參考文件相互驗證,該文件定義了選定酬載上相同的從零開始的 XOR 行為。
什麼時候 BCC 速查表是用錯的工具
8 位元 BCC 能偵測一些意外變更,但因為碰撞太多,無法用於任何更嚴肅的用途。如果協定要求的是 CRC-16、CRC-32、Fletcher-16、Fletcher-32、Adler-32、網際網路檢查碼,或任何具名的加密雜湊(例如 MD5、SHA-1 或 SHA-256),那麼本速查表中的三個公式都無法對應。單一位元組的 XOR 可以藉由翻轉一個相符的位元組,被刻意調整成任何想要的值;加法式 LRC 也是一樣。因此,這些值絕不能用於授權指令、保護憑證、驗證軟體下載,或認證不受信任的網路流量。請使用協定實際指定的安全性機制,通常是 MAC 或數位簽章,而非檢查碼。
若想從不同角度了解相同的位元組層級錯誤偵測,可以參考BCC 檢查碼 API 替代方案指南,其中說明本地計算機如何避免託管 API 的來回延遲與資料外洩。當手冊指定的是較寬的檢查碼(例如 16 位元 XOR 配對或更常見的 32 位元 CRC)時,計算公式會有所不同,使用專用工具是較安全的選擇;CRC32 計算機涵蓋了最常見的較寬替代方案。
如果你正在權衡各種選項,Base58 解碼詳解:原始位元組如何還原對此有詳細說明。