BCC 校驗和是將所有酬載位元組進行 XOR 運算後產生的一個位元組,因此接收端可以偵測意外的傳輸錯誤。BCC 代表 Block Check Character(區塊檢查字元),這個術語涵蓋一系列的一位元組檢查方式,而不是指單一通用的演算法。最常見的形式是 XOR-8:從零開始,對每個位元組執行位元 XOR,最終得到的八位元值就會成為伴隨訊息傳送的檢查位元組。由於 XOR 運算符合交換律且不涉及進位,因此位元組的順序並不重要,加入一個額外的零也不會改變結果。由於結果僅佔一個位元組,從 00 到 ff 的每個可能值都對應到許多不同的酬載,這就是為什麼 BCC 能夠抓出明顯的意外翻位,卻很容易遭到偽造。初學者應該將 BCC 視為一個廉價的完整性煙霧偵測器,用於捕捉傳輸過程中的隨機錯誤,它不是安全機制,也無法保證位元組送達時沒有改變。

bcc checksum for beginners
初學者如何計算 BCC 校驗和

用白話說 BCC 實際代表什麼

BCC 代表 Block Check Character,雖然這個名稱聽起來很正式,但概念其實很直觀。你將訊息的位元組用一條簡單的規則組合起來,最後得到一個額外的位元組,伴隨原始資料一起傳送。當接收端收到訊息時,會在本地重複同樣的組合程序,並檢查自己的結果是否與附加的位元組相符。不相符就代表資料在傳輸過程中遭到破壞。

初學者容易感到困惑的原因在於「校驗和」這個詞並非指單一演算法。不同的廠商和通訊協定使用相同的詞彙,卻代表不同的計算方式。有些描述的是簡單的 XOR 折疊,有些描述的是加總,還有些描述的本質上是換了名字的 CRC。最安全的做法是先閱讀裝置或通訊協定文件中的確切公式,再相信任何工具的輸出結果。

就本指南而言,BCC 指的是 XOR-8 區塊檢查字元:從零開始,將每個選定的酬載位元組進行 XOR 運算所產生的一個位元組,不做任何最終轉換。這個定義符合廠商參考資料,例如 BALTECH 的 XOR-8 BCC 說明文件。

在現實生活中會在哪裡遇到 BCC

BCC 值出現在小型嵌入式裝置透過低速連結交換短訊框,且需要廉價方式來偵測位元翻轉的地方。你最常會在以下情境看到它們:

  • RFID、條碼和門禁硬體的讀寫器通訊協議。
  • RS-232 和 RS-485 連結上的工業串列通訊協定,其訊框結構簡單,且控制器記憶體有限。
  • 馬達控制器、感測器和秤重器的自訂指令-回應通訊協定。
  • Modbus ASCII 訊框,其中一個密切相關的值稱為 LRC,扮演的角色與其他場合的 BCC 相同。

在所有這些情況中,BCC 位於訊框末端,恰好佔一個位元組,並由接收端重新計算。如果你的目標是與這些裝置之一的進行通訊,你不需要發明新演算法;你只需要逐位元組計算出裝置所預期的值即可。

XOR-8 公式,不含專業術語的說明

XOR 是一種位元運算,當兩個輸入位元不同時回傳 1,相同時回傳 0。套用於兩個完整位元組時,它會逐位元進行運算。XOR-8 BCC 公式為:

BCC = b1 ⊕ b2 ⊕ b3 ⊕ ... ⊕ bn

其中每個 bi 是按順序排列的酬載中的一個位元組。累加器從 0x00 開始,這點的重要性可能不如你所想,因為與零進行 XOR 是恆等運算。由於 XOR 符合交換律和結合律,位元組的順序並不重要;{01, 02, 03, 04} 的運算結果與 {04, 03, 02, 01} 的結果相同。

假設四個酬載位元組為 01 02 03 04,逐步進行折疊運算:

  • 0x00 ⊕ 0x01 = 0x01
  • 0x01 ⊕ 0x02 = 0x03
  • 0x03 ⊕ 0x03 = 0x00
  • 0x00 ⊕ 0x04 = 0x04

BCC 為 0x04。對應的 256 取模加總為 0x0A(1 + 2 + 3 + 4),而 Modbus ASCII LRC(即該加總的二補數)則為 0xF6(因為 0x0A + 0xF6 = 0x100 ≡ 0 mod 256)。這三個數字來自相同的輸入,但各自告訴你關於輸入的不同資訊。

如何為你自己的位元組計算 BCC

  1. 選擇正確的輸入模式。如果你的裝置文件將酬載記錄為可讀文字,請選擇 UTF-8 文字。如果文件提供位元組序列(例如「01 02 03 04」),請選擇十六進制位元組,並貼上完全相同的位元組對。
  2. 確認 BCC 涵蓋哪些位元組。閱讀通訊協定指南的訊框結構章節。大多數通訊協定會包含指令和資料位元組,但會排除起始分隔符號、長度位元組或歸位/換行字元組。有些則包含所有內容;幾乎沒有任何通訊協定會將 BCC 位元組本身納入計算,因為那會形成循環依賴。
  3. 只輸入這些位元組。在十六進制模式下,每個位元組必須恰好是兩個十六進制數字;位元組之間可以有空格,但逗號、連字號、0x 前綴和多餘註解將會被拒絕,而不是被默默重新解讀。
  4. 執行計算。開啟 校驗和計算工具,貼上位元組,然後按下計算按鈕。結果區塊會顯示三個值(XOR-8 BCC、Modbus ASCII LRC 和 256 取模原始加總),以及公式實際處理的位元組總數。
  5. 與文件進行比對。選擇與你裝置描述的公式相符的標記值。如果文件稱其為「BCC」且意指 XOR-8,請複製 XOR-8 BCC。如果該欄位稱為「LRC」且參照 Modbus ASCII 指南,請複製 Modbus ASCII LRC。第三個值是一個診斷值,可協助你辨識廠商實際指的是哪種慣例。
  6. 只傳送裝置預期的位元組。Modbus ASCII 將 LRC 以兩個 ASCII 十六進制字元傳送,置於訊息主體之後、CRLF 之前。原始串列 BCC 通常以單一個原始位元組傳送。

結果中的位元組計數行是你的安全網。如果它顯示你處理了七個位元組,但文件暗示是八個,你幾乎肯定是少輸入了一個位元組。略過這個檢查的初學者,往往會花上一整個下午納悶為何每個封包都被拒絕。

從相同輸入可能看到的三種公式

標記 公式 典型用途
XOR-8 BCC 使用 XOR 將每個位元組折疊進累加器,從 0x00 開始 許多讀寫器和自訂串列通訊協定
256 取模加總 將每個位元組相加,僅保留低八位元 診斷用的中間值;某些產品將此稱為 BCC
Modbus ASCII LRC 256 取模加總的二補數(等同於加總的負值 mod 256) Modbus ASCII 訊框,不含起始冒號和結尾 CRLF

這三個值都衍生自相同的位元組序列,因此並非獨立的檢查方式。將它們並列顯示是一種診斷手段,可在文件說明模糊時判斷裝置實際預期的是哪種慣例。

初學者在 BCC 值上常犯的陷阱

錯誤 失敗原因
將起始冒號或結尾 CRLF 納入計算 Modbus ASCII 明確將這些訊框字元排除於 LRC 之外
將 BCC 位元組本身納入計算 將你正在嘗試計算的位元組納入,會使結果依賴於自身
未確認編碼就將原始位元組當成文字貼上 非 ASCII 字元佔用多個 UTF-8 位元組,會導致顯示的位元組計數跳動
未確認公式就相信「校驗和」這個詞 同一個詞可能涵蓋 XOR、加總、CRC 及其他不相關的公式
裝置要的是原始位元組,卻將 BCC 以 ASCII 十六進制傳送 兩個 ASCII 字元(「04」)與一個二進制 0x04 並非同一個位元組

如果你看到某個裝置總是以相同的 BCC 位元組拒絕所有訊框,通常問題出在訊框結構或編碼,而非公式本身。

BCC 無法為你做到的事

一位元組的檢查機制本質上就很小。它能捕捉翻轉單一位元所造成的意外損毀,但無法捕捉所有錯誤,也並非安全機制。請將 BCC 視為除錯信號,而非保證:

  • 兩個不同的訊息可能共用相同的 BCC。對於任何非平凡的酬載,每個可能的 BCC 值都對應到許多不同的訊息,因此碰撞是正常的。
  • 知道公式的攻擊者可以調整任何酬載,使 BCC 保持不變。請勿使用 BCC 來驗證指令或認證韌體。
  • BCC 無法偵測出所有錯誤模式。兩個相同位元組的交換,或恰好落在某些位元位置上的四位元錯誤,可能使 BCC 保持不變。
  • 如果你的通訊協定要求使用 CRC-16、CRC-32、Fletcher、Adler、網際網路校驗和或具名的加密雜湊,那麼 XOR-8 BCC 就是錯誤的工具。請使用該通訊協定指定的安全機制。

對於其他所有情況(感測器訊框、RFID 讀取、秤重指令、Modbus ASCII 輪詢),正確建框的 BCC 正是接收端所需的。校驗和計算工具可從相同輸入計算標記的 XOR-8 BCC、Modbus ASCII LRC 以及診斷用的 256 取模加總,因此你無需猜測即可對應裝置實際需要的公式。從這裡進階的初學者,通常會把 BCC 校驗和速查表:公式、位元組與限制 放在身邊,以便在開始建構實際訊框時快速參考。

如果你正在權衡各種選項,BCC 校驗和免費免註冊:在瀏覽器中取得數值 有詳細說明。