Base32 解碼是把一個由 A-Z 與 2-7 編碼而成的字串轉回可讀文字的過程,方法是把這兩個 32 個符號視為五個位元一組來讀取,再重新組合成原始的位元組。對初學者來說,這個任務比看起來簡單:每個 Base32 字串都是 26 個大寫英文字母與數字 2 到 7 所組成的有限清單,以八個字元一組分塊,結尾可以有選擇性的等號。一旦理解等號不是一個字元,而是標示最後一組不完整的記號,剩下的解碼過程就變成機械式的操作。本指南會帶你了解 Base32 究竟是什麼、為什麼它的字母表長成那樣,以及如何使用 瀏覽器端的 Base32 編碼/解碼工具來還原原始文字,而且完全不必把資料傳送到任何地方。如果你正盯著像 JBSWY3DPEB3W64TMMQ====== 這樣一串字母,完全不知道怎麼回到原始訊息,那你來對地方了。讀完本文後,解碼 Base32 會比較不像在瞎猜,而更像在讀表格。
Base32 究竟是什麼
Base32 是 RFC 4648 中所定義的數種「二進位轉文字」編碼之一,這個網路標準同時也描述了 Base16 與 Base64。名稱本身就是最清楚的線索:它正好使用 32 個字元來表示二進位資料。這 32 個字元是 A 到 Z 共 26 個大寫字母,加上數字 2 到 7 共 6 個。它們組合起來剛好填滿一個字母表,對應到從 0 數到 31 的二進位計數方式,其中 A 代表 0、Z 代表 25、2 代表 26、7 代表 31。
每個字元代表一個五位元的值。因為五個位元只能表示 0 到 31 的數字,所以每個字元對應到一個固定的值。八個 Base32 字元代表五個輸入位元組,因為 8 乘以 5 等於 40 位元,而 40 位元等於 5 個位元組。當輸入不是五個位元組的倍數時,編碼器會在最後一組補上零,然後再補上等號,直到結果長度為八的倍數。這就是為什麼在標準 Base32 輸出中會出現等號的唯一原因:它不是資料的一部分,而是標示最後一組不完整的記號。
對初學者來說,最值得記下來的最實用表格就是字母表的錨點本身。依 RFC 4648,索引 0、25、26 與 31 分別對應 A、Z、2 與 7。如果你在 Base32 字串中看到像 0、1、8 或 9 這樣的數字,那就不是標準 Base32,而是其他替代字母表,例如 Base32hex 或 Crockford Base32。
為什麼人們會使用 Base32
Base32 會出現在二進位資料必須以手動方式抄寫、以純文字記錄,或儲存在無法明確分辨大小寫的系統中的情境。初學者最常遇到的情況是 TOTP 驗證器的密鑰,它通常以 16 字元、26 字元或 32 字元的 Base32 字串形式發放,再貼進像是 Google Authenticator 這類應用程式中。DNS 記錄值、部分舊系統的檔案校驗碼,以及某些授權金鑰也都遵循相同的模式。
它在這些情境中勝過 Base64 的原因是大小寫不敏感。Base64 使用小寫 a 到 z、大寫 A 到 Z、數字以及兩個額外的符號,這表示手動抄寫的字串可能會變成不同大小寫而導致解碼失敗。Base32 只使用大寫字母與六個數字,所以抄寫時即使發生大小寫錯誤,只要解碼器把字母視為大小寫不敏感,就不會影響結果的意義。
重要的是要理解 Base32 不是加密。RFC 4648 把 Base16、Base32 與 Base64 描述為可逆的二進位轉文字編碼,不具備機密性、完整性保護,也不處理密碼。任何拿到編碼字串的人都能解碼。請把任何以 Base32 儲存秘密視同純文字,而且絕不能單獨依賴 Base32 來保護密碼、權杖或個人資料。
解碼前你必須知道的三條規則
在把 Base32 字串貼進解碼器之前,有三條規則可以涵蓋大多數初學者的疑惑。
規則一:只有 A 到 Z 與 2 到 7 是合法的。字串主體中出現的其他字元(除了等號與貼上的空白字元之外)代表使用了不同的編碼,或是發生了複製貼上錯誤。
規則二:等號只會出現在最末端。標準有填補的 Base32 字串長度一定是八的倍數。最後一組一到六個等號代表缺少多少位元組的資料。一個完善的解碼器也接受未填補的輸入,只要總字元數對應到整數個輸入位元組(5、10、15 等等)。
規則三:輸入時大小寫無意義,輸出時為大寫。解碼時小寫字母等同於大寫,但標準的編碼形式永遠是大寫。為了方便使用,有些解碼器也會自動去除貼上的空格、Tab 與換行,這表示分成好幾行的字串會跟一整行一樣正常運作。
記住這三條規則,解碼就會變成一步驟的動作:貼上字串、讀取輸出、複製結果。
標準測試向量
RFC 4648 公布了七組測試向量,每個符合規範的解碼器都必須重現這些結果。它們是第一次檢驗工具時最安全可用的字串。
| 輸入文字 | 標準 Base32 輸出 |
|---|---|
| (空字串) | (空字串) |
| f | MY====== |
| fo | MZXQ==== |
| foo | MZXW6=== |
| foob | MZXW6YQ= |
| fooba | MZXW6YTB |
| foobar | MZXW6YTBOI====== |
這些範例直接取自 RFC 4648 第 10 節,存在的目的就是讓初學者可以在信任工具處理真實資料之前,先用已知的正確答案來驗證解碼器。如果你的工具對上述任何一個輸入回傳不同的結果,那就不是嚴格遵循 RFC 4648 的實作。
如何在瀏覽器中解碼 Base32
對初學者來說,最快的 Base32 字串解碼方式就是使用在本地端執行的瀏覽器端工具。Base32 編碼/解碼工具遵循標準的 RFC 4648 字母表,在當前分頁中執行,而且絕不會上傳你的輸入。請依序執行下列步驟。
- 開啟 Base32 編碼/解碼頁面,並把模式選擇器切換為 Decode(解碼)。
- 把 Base32 字串貼進輸入區域。貼上的空格、Tab 與換行會自動被去除。
- 讀取輸出區域。如果字串乾淨地解碼為 UTF-8 文字,原始訊息就會立即出現。
- 如果輸出區域顯示的是特定的驗證錯誤而不是文字,請閱讀訊息內容;它會指出問題所在,例如無效的填補、非標準的尾端位元,或是非 UTF-8 位元組。
- 若要確認來回轉換的正確性,請點擊 Swap direction(切換方向);解碼後的文字會移到輸入區域,模式切換為 Encode(編碼),原本的 Base32 會重新出現以便比對。
- 點擊 Copy output(複製輸出)把解碼後的文字放到剪貼簿。
整個過程只需幾秒鐘,而且不會在任何伺服器留下任何紀錄,因為轉換是在瀏覽器的 JavaScript 執行環境中完成的。
逐步解碼範例
為了讓位元運算的過程具體可見,這裡使用上表中第二個 RFC 向量進行單一字母的來回轉換示範。
從編碼字串 MY====== 開始。結尾的等號不帶任何資料,所以解碼器會把它們去除;只有 M 與 Y 兩個字母會貢獻出結果。
使用 RFC 4648 字母表,把每個字母對應到它的五位元值。M 是英文字母中的第 13 個字母,但從零開始索引則為值 12,以二進位寫成 01100。Y 是第 25 個字母,值為 24,寫成 11000。解碼器把這兩個五位元組串接成一個 10 位元的位元流:01100 接著 11000,得到 0110011000。
接著解碼器把這 10 個位元從左邊開始分成八位元一組的位元組,最後一組不滿的位元以零補齊:01100110 接著 00。
去掉補零的位元,剩下的單一位元組為 01100110。以十進位表示是 102,也就是小寫字母 f 的 ASCII 碼。
因此 MY====== 解碼為 f,與 RFC 測試向量所保證的結果完全相同。同樣的程序適用於任何長度的輸入,等號標示出最後一個位元組不完整的位置,並以少量的尾端零位元填補該差距。
解碼失敗時如何解讀驗證錯誤
大多數初學者在第一次解碼 Base32 時都會遇到相同的幾種錯誤。嚴格的解碼器會拒絕這些情況,而不是產生錯誤的答案,而且錯誤訊息通常會告訴你是哪一種。
- 在 2 到 7 之外的標點符號或數字表示來源字串使用了不同的字母表(Base32hex、Crockford、z-base-32),或在傳輸過程中被損壞。
- 出現在中間的等號永遠不合法。填補符號只能出現在字串的末端,永遠不能出現在最後一組字母與數字之前。
- 不可能的資料長度發生在未填補的長度對應不到整數個輸入位元組時(5、10、15 等等)。
- 不正確的填補數量代表該字串被手動編輯過,或是從使用不同填補規則的工具複製過來的。
- 非零的未使用尾端位元表示原本的編碼器違反了「在把最後一組對應到字母之前先以零填滿」的規則。
- 無效的 UTF-8會在解碼出來的位元組雖然是有效的 Base32,但不代表文字時回報。二進位承載、加密過的資料片段,以及壓縮資料都屬於這一類,無法用替換字元轉成文字字串。
解碼器寧願回報這些情況也不默默用替換字元取代,是因為訊息中間出現一個錯誤位元組比完全沒有輸出更糟。嚴格的 UTF-8 解碼器確保你只會看到正確的文字,或清楚說明解碼為何在該點停止的明確理由。
驗證來回轉換
一旦手上有解碼後的字串,最簡單的檢查方式就是再編碼一次並做比對。Base32 編碼/解碼工具中的 Swap direction(切換方向)控制項會把解碼後的文字移到輸入方塊中,把模式切換為 Encode(編碼),並產生原本的標準輸出。如果重新產生的 Base32 與你一開始的字串相符(忽略大小寫),那就代表來回轉換是乾淨的。
這件事很重要有兩個原因。第一,它能確認輸入從一開始就是有效的 Base32,而不是某個剛好解碼出看似合理結果的損壞字串。第二,它讓你能分辨出 RFC 4648 Base32 與密切相關的 Base32hex 編碼之間的差異,後者使用數字 0 到 9 與字母 A 到 V,而不是 2 到 7 與 A 到 Z。這兩種編碼不能互換,來回轉換的檢查可以快速抓到這個差異。
接下來,對初學者最實用的延伸閱讀是 Base32 解碼備忘單:字母表、填補與錯誤,它提供單頁的參考資料,涵蓋你在從簡單的 UTF-8 文字進展到更長字串與更嚴苛的資料來源時,會遇到的最常見解碼情境。
如果你正在權衡選項,Base58 Decode JavaScript:純瀏覽器方法對此有詳細說明。