什麼是 Base32 和 Base58?
它們是同一個問題的兩種答案:一個只能承載文本的通道被要求承載位元組。Base32 和 Base58 既不是加密也不是雜湊 — 它們既不隱藏任何內容,也不縮短任何內容。它們用一組固定的可讀字元改寫一個位元組串,任何知道用的是哪一組的人都能直接還原。偏好哪一個的唯一理由,是接收方拿這些字元去做什麼。
兩個家族以完全不同的方式完成這種改寫,而這個差異幾乎解釋了本頁所有的意外:
- 位元打包 — Base32、Base32 Hex、Crockford Base32、z-base-32。位元組被切成固定分組,每五個位元變成一個字元。輸出長度可由輸入長度推知,最後未填滿的分組要麼用填充字元標記,要麼保持短缺。
- 大數轉換 — 所有 Base58 表。整個位元組串被當作一個以 256 為底的巨大數字讀入,再以 58 為底寫出。沒有分組也沒有填充;長度不能被整除,每個前導零位元組變成一個前導零符號。
資料位元的去向:Base32 每字元承載 5 個位元,所以每 5 個輸入位元組需要 8 個字元 — 約膨脹 60%。Base58 每字元約 5.86 個位元,膨脹約 37%。Base64 每字元 6 個位元,膨脹 33%。字母表越大越短、也越難讀出聲,這正是每種方案所做的取捨。
本頁的七個字母表
每個字母表都完整印出而非口頭描述,因為兩個在同名之下列印不同字元的工具,無論標籤怎麼寫都不會彼此一致。RFC 4648 行是規範性的;Crockford 與 z-base-32 行遵循格式作者釋出的定義;三個 Base58 行是廣泛流傳的慣例而非標準,因此分開列出。
Crockford Base32 與模 37 校驗符號
該字母表去掉了 I、L、O 和 U,使任何符號都不可能被讀成另一個。剩下的部分輸入時大小寫不敏感:i 和 l 讀作數字 1,o 讀作數字 0,連字元只用於讓長串更易讀。在此基礎上,格式還定義了可選的校驗符號:把符號串當作 32 進位制數求值,對 37 取模,值 32 到 36 用五個額外符號書寫。
校驗符號是對符號串而非對位元組計算的:因為編碼器對最後一組做零擴充套件,解碼同樣的字元總能回到同一個值。這就是表中的校驗值可以只憑編碼列手工復現的原因。五個額外符號是 *、~、$、= 和 U,對應值 32、33、34、35、36,因此校驗符號並不總是數字或字母。
z-base-32
z-base-32 保留 RFC 4648 Base32 的五位元打包,只改變三十二個字元的順序。這個順序讓一個人最可能需要抄寫的字元恰好是最容易寫、最難混淆的那些。它沒有填充,所以讀者必須知道一個值應該有多少個符號;這就是一個優先為手寫閱讀設計的格式的代價。
Base58Check:一個版本位元組、載荷、四個校驗和位元組
Base58 本身無法把輸錯的字串和正確的區分開,因為其 58 個字元的幾乎任意組合都是一個合法數字。Base58Check 通過把資料裝進一個外殼來解決這個問題:一個版本位元組,然後是載荷,然後是對前兩部分連續做兩次 SHA-256 取前四個位元組。接收程式重新計算這四個位元組,不一致就拒絕該字串。版本位元組告訴錢包它看到的是付款地址、指令碼地址還是私鑰。
轉換器下方的生成器以十六進位制輸入版本位元組和載荷並寫出 Base58Check 字串;校驗器讀回一個字串,剝離四個校驗和位元組,重新計算它們,並報告找到的和期望的兩個值。這裡校驗和錯誤意味著字串被輸錯或篡改 — 絕不意味著載荷本身錯誤,因為載荷從未被解釋。
常見誤解
- “Base64 是加密。”不是。沒有金鑰也沒有秘密;任何人都能還原輸出。Base32 和 Base58 處於同樣的位置,把一個值依次過三遍也不會增加任何保護。
- “Base58 字串就是比特幣地址。”只有當它同時通過 Base58Check 校驗並攜帶接收軟體認識的版本位元組時才是。Base58 字串還出現在許多其他場合,包括完全沒有校驗和的普通識別符號。
- “三個 Base58 字母表可以互換。”它們用同樣的 58 個字元、三種不同順序,同樣的位元組會產生三個不同字串。工具必須被告知用哪一個,而本頁總是說明它用的是哪一個。
- “填充是值的一部分。”
= 字元只標記最後一組。兩個僅填充不同的 Base32 字串描述同樣的位元組,這就是解碼器接受去掉填充的字串的原因。
- “任何字元都行。”每個字母表都是固定集合。來自集合之外的字元沒有值,所以解碼器會停下來指出該字元及其位置,而不是去猜。
常見問題
為什麼 Base32 用 2-7 而不是 0-9?因為 RFC 4648 選擇字母表的原則是:只使用域名允許包含的字元,並且容易讀出聲。當自然排序更重要時,改用 0-9 A-V 的 Base32 Hex。
為什麼 Base58 字串經常以 1 開頭?輸入的每個前導零位元組變成一個前導 1(Bitcoin 和 Flickr 字母表的首字元)。版本位元組 0x00 就是一個零位元組,所以大多數比特幣主網地址恰好以一個 1 開頭。
示例按鈕載入什麼?屬於當前方案和當前方向的例子,絕不是固定文本。編碼器得到該方案自己的示例文本 — Base32 與 Base32 Hex 用 RFC 4648 第 10 節向量、Crockford 的 12345、上文印出的 z-base-32 行 — 解碼器得到所選字母表的編碼字串,這正是示例能雙向使用的原因。三個 Base58 行有意使用同一文本,因此切換方案再點示例,可以並排看到同樣 58 個字元的三種排序。勾選 Crockford 校驗符號時,解碼器拿到的是末尾帶符號的值,這是能看到校驗器接受一個值的唯一途徑。
本頁會把我的資料發到別處嗎?不會。所有轉換都在這個瀏覽器標籤頁中完成,頁面不包含任何網路請求。這也是直接從磁碟開啟檔案也能用的原因。
存金鑰該用哪一種?TOTP 和 HOTP 驗證器金鑰通常是 RFC 4648 字母表的 Base32,因為金鑰需要手工輸入。用接收軟體要求的那一種,並且永遠不要指望編碼本身提供保密性。