Android 上的區塊檢查字元 (BCC) 幾乎都是由裝置規格指定要涵蓋的訊息位元組上套用一個八位元 XOR,並回傳一個單一位元組,接收端會再次將其折疊進去並進行比對。當你在手機上需要該值時,最直接的方式是使用 Checksum Calculator,它接受十六進位位元組或 UTF-8 文字,從零開始執行 XOR-8 折疊運算,並將結果以兩個小寫十六進位數字呈現,同時還會顯示 Modbus ASCII 縱向冗餘檢查 (LRC) 以及原始位元組模 256 的總和。這個計算工具在行動瀏覽器中於本機執行,因此不需要測試 APK、不需要設定 Termux,也不需要搭配的藍牙工具。許多序列通訊、RFID 讀取器以及工業藍牙協定中所描述的訊框完整性位元組,使用的就是同一個 XOR-8 公式;它同時也是 Stack Overflow 上有關 Android 手機與序列裝置通訊的解答所引用的公式,也是在外場筆記型電腦或平板上逆向工程未知封包擷取時的標準起點。

bcc checksum on android
Android 上的 BCC 校驗碼:在瀏覽器中計算 XOR-8

為何基於瀏覽器的 BCC 計算工具適合 Android 工作流程

Android 開發人員在測試序列或藍牙外接裝置時,經常會遇到瓶頸:裝置要求每道指令的結尾都必須帶一個位元組,但 SDK 並未提供對應的輔助工具,而且在現場除錯時必須即時計算出該位元組。基於瀏覽器的計算工具可以省去 Kotlin 程式碼片段或小型測試 Activity 所需的「建置-安裝-啟動」循環。你只需貼上位元組、讀取標示好的十六進位值,然後將其複製到下一個外送封包中。由於結果是以三種具名公式呈現,當裝置說明文件使用「BCC」一詞的方式與你的原始 XOR 不符時,你也能夠察覺——這在將工業協定的程式碼移植到另一個協定時,是常見的混淆來源。

當你正在逆向工程從邏輯分析儀或藍牙嗅探器擷取到的訊框時,同一個工具也能派上用場。你可以貼上分析儀所記錄的位元組,查看計算工具實際處理了多少個位元組,並確認在執行 XOR 之前沒有任何分框字元被悄悄吸收掉。該頁面也公開設定了一個 500,000 位元組的硬性上限,因此即便是數 MB 的擷取資料也不會讓分頁當機;較大的輸入會以清楚的錯誤訊息拒絕處理,而不是默默截斷,而格式錯誤的十六進位資料則會被回報,不會產生一個可能被誤認為真實校驗碼的部分值。

XOR-8 BCC 公式的實際運作方式

XOR-8 從零開始,使用 XOR 運算子將每個涵蓋的位元組折疊進一個八位元累加器。由於 XOR 忽略進位且其反運算即為自身,因此執行中的總和只是所有輸入位元組的連續 XOR;高位元永遠不會遺失。以 0x8A、0x01、0x01、0x11 這組序列為例,計算過程如下:0x00 XOR 0x8A = 0x8A,接著 0x8A XOR 0x01 = 0x8B,然後 0x8B XOR 0x01 = 0x8A,接著 0x8A XOR 0x11 = 0x9B,因此接收端預期在結尾看到的位元組就是 9B。這個單一位元組就是 BCC;接收裝置會在資料酬載上重複同樣的折疊運算,若其計算結果與你所傳送的不一致,就會拒收該訊框。

可交換性正是這個校驗碼如此便於移植的原因:位元組進行 XOR 的順序並不影響結果,因此任何不改變位元組集合的位元組範圍重排,也不會改變 BCC。這個特性同時也使得該機制存在許多碰撞;兩個不同的訊框可能會 XOR 出同一個位元組,這就是為什麼 XOR-8 BCC 被視為錯誤偵測的提示,而不是身分驗證機制。BALTECH BCC 參考資料記錄了八位元 XOR 變體,是計算工具所實作公式的其中一個出處。

從手機瀏覽器計算 BCC 校驗碼

這個 Android 專屬路徑只需要頁面網址以及裝置的位元組表示方式。

  1. 在 Chrome、Firefox 或手機上已安裝的任何其他瀏覽器中開啟 /encoding/checksum-calculator/。該頁面不需要登入或帳號。
  2. 若你的裝置以位元組通訊,請將輸入模式切換為十六進位;若裝置傳送可列印的 ASCII 指令(例如鍵盤掃碼或 RFID 標籤酬載),則保持文字模式即可。
  3. 依照裝置規格的定義,逐字輸入或貼上酬載內容。在十六進位模式下,每個位元組以兩個十六進位數字輸入,位元組之間可以選擇性加上空白;計算工具會拒絕 0x 前綴、逗號、奇數半位元組以及行內註解,而不是猜測你的意思。
  4. 若你的協定要求省略前導冒號或結尾的 CRLF,請在貼上之前先移除這些位元組。計算工具並不會為你剝除分框字元,因為「省略」是各協定特有的規則,必須明確遵守。以 Modbus ASCII 規格為例,LRC 計算所接收的位元組中會排除起始冒號與結尾的 CRLF,而這項排除動作必須由使用者自行處理。
  5. 點擊 Calculate,讀取 XOR-8 BCC 下方的兩個十六進位數字。另外兩個欄位(Modbus ASCII LRC、模 256 總和)屬於診斷輔助;只有在廠商指南明確要求該類型的值時,才加以複製或比對。
  6. 將 XOR-8 BCC 位元組附加到外送封包,透過藍牙 SPP 插槽或 USB 序列埠應用程式發送,並觀察裝置的回應。若訊框遭拒,首先應檢查結果下方的位元組計數——若出現不符,代表在執行 XOR 之前有位元組被多加或漏掉。

整個程序在頁面載入後無需網際網路連線,這在工廠現場 Wi-Fi 受到嚴格管制,以及 Android 手機透過防火牆後方僅支援序列通訊的裝置進行連線的場域中,格外重要。

三個輸出值各自的意義

輸出公式在 Android 及嵌入式裝置上的典型用途
XOR-8 BCC從 0x00 開始,將每個涵蓋的位元組進行 XOR序列訊框、RFID 讀取器、簡易裝置協定
Modbus ASCII LRC將位元組總和取模 256,再取二補數Modbus RTU/ASCII 訊息完整性
模 256 總和將位元組總和,只保留低八位元LRC 步驟的診斷中間值

XOR-8 欄位幾乎永遠是 Android 開發人員貼上作為序列訊框結尾位元組的值。Modbus ASCII LRC 是二補數,代表它在數學上是原始位元組總和的負值;這兩個值在模 256 之下相加永遠為零。當說明文件談到「BCC」,但位元組與 XOR 折疊結果不符時,可改用 Modbus 或總和欄位,確認廠商實際使用的是哪種慣例,然後以該值發送訊框。

依據廠商說明文件解讀計算工具的輸出

硬體廠商對 BCC 一詞的使用並不一致。有些廠商將其視為加法校驗碼的同義詞,有些則視為 CRC,還有些則視為 LRC。上方連結的 BALTECH BCC 參考資料記錄了八位元 XOR 變體,在除錯時值得與計算工具並排開啟;較為全面的 XOR-8 原理說明指南 以及 公式與限制速查表 也適合作為與計算工具搭配使用的快速參考。之所以同時顯示三個具名值,是為了讓你能在不同慣例之間切換,直到裝置正確回應,而不必在每次發現說明文件採用不同定義時,還得重新編寫手機上的測試程式碼。

一個實用的 Android 除錯順序如下:將裝置預期的位元組貼入十六進位模式,擷取 XOR-8 BCC,發送訊框;若遭拒,則切換到模 256 總和欄位,嘗試將其作為結尾位元組。許多消費級裝置雖然標示為「校驗碼」,實際上卻期待的是簡單的總和;計算工具提供三個具名輸出,可讓你免於為每種慣例撰寫一次性的 Kotlin 公用程式——當同一支手機需要連續測試多個外接裝置時,這點特別有用。

八位元校驗碼何時開始不足

XOR-8 與 Modbus LRC 能捕捉到意外的位元翻轉,但無法驗證發送者的身分。兩個經過刻意建構的訊框可以 XOR 出同一個位元組,而一個位元組的總和也能輕易調整為任何想要的值。凡是涉及傳遞憑證、授權指令、驗證軟體下載,或信任未經驗證網路通道內容的協定,都需要訊息驗證碼、數位簽章或更寬的 CRC;計算工具中的一位元組結果無法滿足上述任何需求。若你的目標協定使用的是 CRC-16、CRC-32、Fletcher、Adler、網際網路校驗碼或任何具名的加密雜湊,正確的工具完全是另一回事——例如用於 HDLC 訊框的 CRC32 計算工具、用於金鑰驗證的 HMAC 產生器,或用於防竄改偵測的 SHA-256 摘要——而不是 BCC 欄位所產生的八位元值。

然而,對於工作台上的一般除錯工作,同一個八位元值足以追蹤分框錯誤、位元組順序錯誤以及意外的多算或少算錯誤。請在測試筆記中記錄位元組範圍、初始值(XOR-8 欄位永遠為零)以及分框排除規則,如此一來,下一個接手這支手機的人就不必重新做一次已經耗費你整晚的反向探索工作。