繁體中文

開發者工具 · Base64 編碼器和解碼器

Base64 vs hex vs base32:比較將位元組寫入文字的三種方法

· 背景

base64 編碼

相同 16 位元組的 Base64、十六進位和 Base32 密度和可讀性比較
原始 ToolAcre 向量圖

Hex、base32 和 Base64 解決了相同的問題,但在大小、可讀性和安全性方面有不同的權衡。這篇文章對它們的密度、區分大小寫、URL 安全性和人為錯誤進行了比較。

由於 l、1、I 和 O 而輸入錯誤的 API 金鑰 — 十六進位不會出現的具體可讀性故障

將位元組表示為文字的三種常見方法是十六進位、base32 和 base64。它們都解決相同的問題(以可列印 ASCII 表示任意位元組),但在大小、可讀性和錯誤恢復能力方面有不同的權衡。十六進位為每位元組 2 個字元 (F3 A2 B1 ...),因此 16 位元組變成 32 個字元。 Base32 為每個位元組 1.6 字元(每 3 位元組約 5 字元),因此 16 位元組變成 26 個字元。

Base64 為每個位元組 1.33 個字元(每 3 位元組恰好 4 個字元),因此 16 位元組變成 24 個字元或更少。如果檔案大小很重要,base64 是最緊湊的。如果人類轉錄很重要,則 hex 和 base32 更安全。當輸入、複製或說出值時,可讀性差異至關重要。 Hex 使用 0-9 和 a-f (在大多數情況下不區分大小寫)。轉錄通道改變了決定,因為針對機器優化的表示對於人們來說可能會很尷尬。 Base64 區分大小寫並使用兩個標點符號; hex 使用較小的視覺詞彙。這裡的實現測試的是精確的字串,而不是人為錯誤率,因此沒有附加發明的機率。

密度:2×、1.6× 和 1.33× — 每種編碼每個位元組需要多少個字元以及原因

Base32 使用 A-Z 和 2-7,避免紙上容易混淆的 0、1、O 和 I。 Base64 使用 A-Z、a-z、0-9、+ 和 /,(包括大寫和小寫),使其區分大小寫並混合看起來相似的數字(0 與 O、1 與 I 與小寫 l)。十六進位的 API 金鑰可能是 f3a2b1e4; base64 中的相同位元組可能是 86KrvE== (帶填充),或在 base32 中 6VEV7FI= (帶填充)。

如果使用者必須手動輸入數值,則十六進位或 Base32 比 Base64 更安全。 URL 中的保留字元很重要。 Hex 和 base32 對 URL 來說是安全的;兩者都只使用字母數字字元(十六進位也使用 0-9,base32 也使用 2-7)。 Base64 使用 URL 保留的加號和斜線(加號表示表單編碼資料中的空格,斜線是路徑分隔符號)。 Base64 密度直接來自每個輸出符號的六個有用位元和四個字元區塊的填充。十六進位每個符號攜帶四位,即每個位元組兩個字元。 Base32 僅作為比較上下文進行討論,因為該儲存庫既不提供其字母表也不提供編碼器來驗證輸出。

位寬密度 — 精確的 Base64 和十六進位算術,將 Base32 視為比較上下文

URL 參數中的 base64 字串必須進行百分比編碼(加號變成 %2B,斜線變成 %2F),為每次出現加上 4 額外字元。 Base64url(RFC 4648 部分 5)將加號替換為破折號,將斜杠替換為下劃線,從而使其無需百分比編碼即可實現 URL 安全。大多數在 URL 中使用 base64 的 API 實際上都使用 base64url,但檔案中的差異通常並不明確。

TOTP 機密(驗證器應用程式使用的程式碼)通常以 base32 形式分發。 TOTP 註冊畫面顯示 Base32 金鑰,因為它比 Base64 或十六進位的相同位元組更容易鍵入和轉錄。 SHA 雜湊摘要通常以十六進位顯示,因為它是傳統格式,而且十六進位不區分大小寫,因此不太可能出現拼字錯誤。當有人大聲讀出一個值或重新輸入它時,區分大小寫很重要,因為更改一個字母的大小寫會更改其索引。 ToolAcre 準確地保留大小寫,並在不知道人類犯了轉錄錯誤的情況下解碼產生的不同位元組。該表示本身沒有校驗和。

保留字元和 URL 安全性 — + 和 / 咬合的位置,以及 base32 和 hex 如何避免該問題

JWT 使用 base64url。檔案校驗和可能是十六進位或base64;兩者都很常見。這種選擇是歷史慣例,而不是技術上的必然。錯誤恢復能力是一個微妙但重要的區別。 Base32 避免使用數字 0、1、8 和 9(看起來像字母),從而減少轉錄錯誤。 Base64 包含所有數字,使得 1 不明確(是字母 I、小寫 l 還是數字 1?)。

十六進位更容易出錯:0 看起來像 O,l 看起來像 1。必須鍵入或從列印輸出中讀取的校驗和在 base32 中更安全。直接從電腦貼上的 API 金鑰在任何格式下都是安全的;僅當涉及人眼時,可讀性才重要。位元組相同,但編碼不同:​​16 位元組序列 [0xf3, 0xa2, 0xb1, ...] 變成 f3a2b1... 標準 Base64 的加號和斜線需要通道感知處理; URL 安全模式將它們替換為連字符和下劃線。十六進制透過單獨使用數字和字母來避免這些分隔符號。 Base32 約定各不相同,因此本文避免了儲存庫未實現或測試的有希望的安全屬性。

工作範例:所有三種編碼中的相同 16 位元組 — 長度比較和目視檢查

(十六進位)、6VEV7FI=...(base32)和 86KrvE==(base64)。這些字串都不可互換。接收 f3a2b1... 的應用程式需要十六進位並嘗試將其解析為十六進位。如果應用程式需要十六進制,則接收 86KrvE== 將會失敗。編碼格式是資料合約的一部分:發送者和接收者必須就使用哪種編碼達成一致。填充是另一個區別。

He​​x 不使用填充(4 位元組始終是 8 十六進位字符,沒有例外)。 Base32 和 Base64 都使用 equals 填入將輸出對齊到多個字元(對於 Base32 為 8,對於 Base64 為 4)。填充在數學上是必要的;它確保每個 n 位元組輸入產生確定的字元計數。填充規則各不相同:有些應用程式需要填充,其他應用程式允許省略填充。工作比較使用固定位元組序列併機械計算 Base64 和十六進位。它的 Base32 長度可以從五位分組來討論,但省略了精確的 Base32 文字值,因為沒有經過審查的實作會產生它。長度算術和輸出驗證保持不同。

其中每個都是常規的 — 十六進位雜湊值、base32 格式的 TOTP 秘密、JWT 和資料:Base64 格式的 URI

當貼上不含填滿的 Base32 或 Base64 值時,解碼器可能會接受或拒絕它,這取決於實作。加密金鑰和令牌顯示編碼差異。

HMAC 金鑰為 32 位元組,它變成 64 十六進位字元、52 base32 字元(含填)或 44 base64 字元(含填)。分發密鑰時,應記錄編碼。如果檔案說密鑰是 44 base64 字符,但您收到 52 字符,則表示有問題。慣例可以指導讀者,但並不能證明適用性。雜湊摘要通常顯示為十六進制,而 JWT 段使用 Base64url。正確的選擇仍然取決於通道規則、人們是否複製該值以及另一個協定是否已經修復了表示。

這不包括什麼-base58、base85 和校驗和編碼

較短的 base64 編碼使得將令牌更容易適應有字元限制的系統(例如 QR 代碼或 URL)。值的編碼選擇是由它來自的生態系統決定的。 Web API 通常使用 base64url。加密檔案通常使用十六進制。身份驗證器應用程式使用 base32。建構系統時,選擇一種編碼,清楚地記錄它,並堅持使用。

混合編碼(例如 Base64 或 Base32)會帶來混亂。在偵錯時,第一步是識別該值使用哪種編碼; Base64 編碼器和解碼器工具可以透過嘗試多種方式對其進行解碼並查看哪種方式產生合理的輸出來提供協助。沒有一種編碼是普遍更好的。 Base64 對於原始儲存來說是最緊湊的。十六進制對於密碼學家來說是最熟悉的,對於小序列來說也是最容易被人類閱讀的。 Base58、Base85 和校驗和編碼進行了不同的權衡,並在 ToolAcre 的 Base64 面板中不存在。它們的字母表、歧義規則和校驗和應該使用專用的來源和實作來評估,而不是從該工具的測試行為推斷出來。

重點:選擇通道和閱讀器的編碼 — Base64 編碼器和解碼器如何在瀏覽器中覆寫 Base64 情況,以及同一產品中的 SHA 雜湊計算器

Base32 對轉錄錯誤的恢復能力最強。選擇取決於上下文:價值存在於何處、如何共享以及哪些系統將使用它。

了解權衡有助於您在設計 API 或系統時做出明智的選擇。 Base64編碼器和解碼器工具演示了base64編碼;將其與十六進位或 base32 工具一起使用可以讓您看到所有三種格式的相同位元組並了解它們的大小和可讀性差異。對於 Base64 情況,對範例進行編碼,記下確切的 UTF-8 位元組和輸出字元計數,並測試標準標點符號與 URL 安全標點符號。對於摘要工作,請使用單獨的 SHA 面板。保持這些操作不同可以防止編碼選擇被誤認為是雜湊或完整性保護。