知識 · 文字、資料與資安
Base64 編碼是什麼?
簡答
Base64 是只用 64 個可列印字元來表示二進位資料的方法:A–Z、a–z、0–9、+ 和 /,並以 = 作為補位。它把每 3 個位元組拆成四組 6 位元,每組對應一個字元,所以「Man」會變成「TWFu」。這讓二進位資料能安全地透過只接受文字的管道傳送,例如電子郵件、JSON 和 URL,代價是大小增加約 33%。它是一種編碼,不是加密。
開啟Base64Base64 運作步驟
Base64 定義於 RFC 4648。因為 64 = 2⁶,每個輸出字元剛好承載 6 位元,3 個位元組(24 位元)正好對應 4 個字元。
| 步驟 | M | a | n |
|---|---|---|---|
| ASCII 碼 | 77 | 97 | 110 |
| 二進位(各 8 位元) | 01001101 | 01100001 | 01101110 |
- 把 24 個位元接起來:
010011010110000101101110。 - 切成四組 6 位元:
010011010110000101101110。 - 換算成數字:19、22、5、46。
- 逐一查對照表(0 = A、25 = Z、26 = a、51 = z、52 = 0、61 = 9、62 = +、63 = /):T、W、F、u。
- 結果:
TWFu。
用 = 補位
輸入長度不是 3 的倍數時,最後一組會以 0 位元補滿,並用 = 標示缺少的位元組,因此輸出長度一定是 4 的倍數。
| 輸入 | 位元組數 | Base64 |
|---|---|---|
M | 1 | TQ== |
Ma | 2 | TWE= |
Man | 3 | TWFu |
Hello | 5 | SGVsbG8= |
é(UTF-8 位元組 C3 A9) | 2 | w6k= |
n 個位元組編碼後的長度是 4 × ceil(n ÷ 3) 個字元。1 MB 的檔案會變成約 1.33 MB 的文字;MIME 電子郵件每 76 個字元還會加一個換行,額外負擔再略高一點。
Base64 用在哪裡
- 電子郵件附件:早期郵件系統只能傳送 7 位元文字,所以 MIME 以 Base64 編碼檔案。
- Data URL:直接內嵌在 HTML 或 CSS 中的小圖片,寫成
data:image/png;base64,iVBORw0KGgo...。 - 需要傳送圖片、金鑰或憑證等二進位資料的 JSON 與 XML API。
- JSON Web Token(JWT),其標頭和酬載是以 Base64url 編碼的 JSON。
- TLS 憑證與金鑰的 PEM 檔,會把 Base64 包在
-----BEGIN CERTIFICATE-----這類標記行之間。 - HTTP Basic 驗證,會把
username:password以 Base64 編碼後送出。
把圖片以 Data URL 內嵌可以省一次網路請求,但大小會增加 33%,也無法單獨快取,所以通常只對非常小的圖片划算。
Base64、Base64url 與其他編碼
標準 Base64 使用 + 和 /,這兩個字元在 URL 和檔案名稱中有特殊意義。同一份 RFC 中的 URL 安全版本把它們換成 - 和 _,而且常省略 = 補位。
| 編碼 | 字元 | 大小增幅 | 用途範例 |
|---|---|---|---|
| Base16(十六進位) | 0–9、A–F | 100% | 雜湊值、色碼 |
| Base32 | A–Z、2–7 | 60% | 雙重驗證金鑰 |
| Base64 | A–Z、a–z、0–9、+、/ | 33% | 電子郵件、Data URL、PEM |
| Base64url | A–Z、a–z、0–9、-、_ | 33% | JWT、URL 參數 |
常見錯誤
- 文字必須先轉成位元組,通常是 UTF-8。在 JavaScript 中,若字串含有表情符號或中文等 Latin-1 以外的字元,沒有先做 UTF-8 編碼,
btoa()就會拋出錯誤。 - 混用標準與 URL 安全的字元表會導致解碼失敗;用標準解碼器之前,先把
-和_換回+和/。 - 缺少補位可能讓嚴格的解碼器失敗;請補上
=,直到長度是 4 的倍數。 - 電子郵件式編碼產生的換行,必須先移除,有些解碼器才肯接受。
常見問題
為什麼 Base64 會讓資料變大?
每 3 個位元組變成 4 個字元,而每個字元都要用一整個位元組儲存,所以輸出比輸入大約多 33%。
Base64 安全嗎?
不安全。它什麼都沒隱藏,解碼也不需要金鑰。要保護資料請用 AES 等真正的加密,Base64 只用來把結果以文字形式傳送。
Base64 結尾的 = 是什麼意思?
那是補位。一個 = 表示最後一組有 2 個位元組,== 表示只有 1 個位元組。
怎麼辨認 Base64 字串?
它只包含英文字母、數字、+ 和 /(或 - 和 _),長度通常是 4 的倍數,結尾可能有一或兩個 = 號。以 eyJ 開頭的字串常是 Base64 編碼的 JSON,因為以 {" 開頭的 JSON 文字編碼後會以 eyJ 開頭。