Base64 解碼是 RFC 4648 中所定義編碼方式的反向操作,方法是將 64 個符號組成的字母表中,每個字元對應回其 6 位元值,再把這些位元重新組合成 8 位元位元組,並去除用來補滿最後一組的 '=' 填補字元。這個字母表是固定的,且小到可以記住:A–Z、a–z、0–9、'+'、'/',以及用於填補的 '='——剛好是 2⁶ = 64 個符號,這也正是「Base64」這個名稱的由來。解碼是完全確定性的,所以像 'SGVsbG8sIFdvcmxkIQ==' 這樣的字串,只會對應回唯一的一組位元序列,在這個例子中就是 'Hello, World!' 的 ASCII 位元組。幾乎所有業餘解碼器都會搞錯的地方是 Unicode。瀏覽器內建的輔助函式只接受 Latin-1 字碼點,因此 'café'、'你好' 或 '😀' 要嘛會拋出錯誤,要嘛會回傳亂碼。正確的解碼器會走 UTF-8 位元組的路線——先編碼成 UTF-8,再把這些位元組進行 Base64 編碼,解碼時反向操作,並加上嚴格的 UTF-8 驗證,讓格式錯誤的輸入被拒絕而不是被悄悄破壞。這條規則所修正的 Base64 bug,比其他任何方法都多。

base64 decode cheat sheet
base64 decode cheat sheet

Base64 字母表一覽

RFC 4648 §4 明確定義了 64 個可列印字元,索引從 0 到 63。索引 0 是 'A',索引 25 是 'Z',索引 26 是 'a',索引 51 是 'z',索引 52 是 '0',索引 61 是 '9',索引 62 是 '+',索引 63 是 '/'。'=' 並不算是字母表本身的一部分——它只是填補字元,只在最後用來把輸出長度補滿為 4 的倍數。把下面的表格記住,就能用手工解碼短字串:每 4 個輸入字元都會對應回 3 個原始位元組。

IndexCharIndexCharIndexCharIndexChar
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

填補字元:第 65 個符號 '='(索引「pad」)只在結尾使用,把輸出長度補滿為 4 的倍數。URL-safe Base64(RFC 4648 §5)把 '+' 換成 '-'、把 '/' 換成 '_',讓輸出能夠在 URL 編碼中存活——不過你最常碰到的還是上面這種標準形式。

如何在線上解碼 Base64

對於任何比幾個字元更長的內容,請使用 Base64 Encode / Decode 工具。它完全在瀏覽器中執行,套用 RFC 4648 的字母表與填補規則,並透過 UTF-8 進行解碼,讓 emoji 和帶有腔調的字元能正確地往返轉換。

  1. 選擇 Decode 模式,讓箭頭從 Base64 指向 text。
  2. 把 Base64 字串貼到上面的方塊中。隨著你輸入或貼上,解碼後的文字會出現在下面的方塊中——沒有送出按鈕。
  3. 如果要在其他地方使用結果,點擊 Copy。如果要重新編碼解碼後的文字以驗證來回轉換,點擊 Swap 即可反轉方向,不必重新輸入。

填補規則與長度計算

Base64 會把 3 個輸入位元組(24 位元)組成 4 個 6 位元字元(也是 24 位元)。當輸入長度不是 3 的倍數時,最後一組會不足,這時就用 '=' 填補把缺少的位置補滿,讓編碼後的長度維持為 4 的倍數。這就是為什麼 'f'(1 個位元組)會變成 'Zg=='——'Zg' 帶著唯一有用的位元組,接著兩個 '=' 把最後一組補滿為 4 個字元。而 'fo'(2 個位元組)會變成 'Zm8='——1 個 '=' 填補。6 個位元組則完全不需要填補。輸入大小和輸出長度之間的關係是固定的;你可以用下面的表格對任何字串進行合理性檢查。

Input bytesOutput charsTrailing padding
14==
24=
34(none)
48==
58=
68(none)
3k + 04k(none)
3k + 14(k + 1)==
3k + 24(k + 1)=

一般公式是:每 3 個輸入位元組會產生 4 個輸出字元,當剩下 1 個位元組時加 1 個 '=',剩下 2 個位元組時加 2 個 '='。因此編碼後的長度為 ⌈n/3⌉ × 4,其中 n 是輸入位元組數。反過來:如果你只知道編碼後的長度,原始位元組數就是 ⌊3m/4⌋,其中 m 是 Base64 字元數(不含填補字元)。這就是解碼器在不解析 JWT 標頭的情況下估算承載大小的方法。

辨識 Base64 字串的快速特徵

合法的 Base64 形狀非常狹窄,因此在日誌和設定檔中很容易辨認:

  • 長度一定是 4 的倍數(在填補字元還原之後)。
  • 字元僅限於 A–Z、a–z、0–9、'+'、'/'(URL-safe 形式則是 '-' 和 '_')。
  • 結尾唯一合法的字元是 ''、'=' 或 '=='——絕對不會是 '===',也不會在字串中間出現單獨的 '='。
  • 在 MIME 換行輸出中,換行符號會每 60 或 76 個字元出現一次,但會在解碼前被去除。

如果在字串中間看到空白字元,base64-decode 的實作應該將其忽略。如果看到任何不在字母表與填補字元之外的字元,則輸入已損壞、被截斷,或根本就不是 Base64。

破壞大多數解碼器的 UTF-8 陷阱

Base64 本身只認得位元組——它沒有字元的概念。解碼結果要變成有意義的文字,必須先決定這些位元組代表哪種字元編碼。對現代字串而言,那就是 UTF-8:'é' 的位元組是 0xC3 0xA9,'你' 的位元組是 0xE4 0xBD 0xA0,'😀' 的位元組是 0xF0 0x9F 0x98 0x80。直接透過瀏覽器內建的 btoa() 對 '😀' 進行編碼會拋出錯誤,因為 btoa 只接受 0–255 的字碼點。透過正確的 UTF-8 路徑編碼則會產生 8 個 base64 字元:8J+YgA==。

反向操作同樣脆弱。將位元組流視為 Latin-1 的解碼器會把 0xE4 轉成 'ä',看起來合理但其實是錯的。嚴格的 UTF-8 解碼器會拒絕任何無效的 UTF-8 位元組序列,而不是用 U+FFFD 替換字元來替代,因此格式錯誤的輸入會以錯誤的形式呈現,而不是被悄悄破壞。請使用能正確處理這點的解碼器——例如 Base64 Encode / Decode 工具就是透過 TextEncoder 進行編碼,並以嚴格的 UTF-8 解碼器進行驗證。

如果你需要反向轉換——例如把 Base64 位元組轉成十六進位——Base64 to Hex 轉換器能處理標準的帶填補形式,且不會遺失前導零。

在真實世界中會在哪裡遇到 Base64

只要二進位資料必須透過純文字通道傳輸,就會看到 Base64。以下是 5 個日常可以辨識它的場景:

  • data: URI。直接內嵌於 HTML 或 CSS 中的圖片、字型和小型資產,前綴為 data:image/png;base64,.... 逗號之後的整段承載內容就是一大段 Base64 字串。
  • MIME 電子郵件附件。SMTP 訊息主體是 7 位元的,因此附件會以 Base64 編碼,並切成長度為 76 字元的行。
  • JSON Web Tokens。一個 JWT 由 3 個以 Base64URL 編碼、以點分隔的段落組成:標頭、承載內容、簽章。可以解碼承載內容來讀取聲明(claims)——但絕對不是用來信任它們,因為驗證真實性靠的是簽章。
  • HTTP Basic 認證。Authorization 標頭的內容實際上就是 'Basic ' 後面接著 Base64(username:password)。它只是編碼,並非加密——任何伺服器管理員都能讀取。
  • API 承載內容。當 JSON 或 XML API 需要在文字欄位中傳遞二進位資料區塊(校驗和、簽章、檔案預覽)時,Base64 就是慣用的載體。

Base64 是編碼,不是加密

Base64 之所以設計成完全可逆——這正是它的全部意義。任何擁有字母表的人都能在幾秒鐘內解碼任何字串,因此 Base64 提供零機密性。應將其視為在純文字通道之間安全傳輸位元組的方式,絕對不能用來隱藏密碼、API 金鑰或工作階段權杖。如果你在產品說明中看到「以 Base64 加密」,那代表該廠商並不了解兩者的差別。

若要真正的保密,你必須使用基於金鑰的機制:AES-GCM、ChaCha20-Poly1305,或像 RSA-OAEP 這類非對稱式加密機制。而在那些希望任何拿到位元組的人都無法讀取、但又不需要將其解密回原貌的情境下,單向雜湊函式(SHA-256、SHA-512)才是正確的工具。Base64 與這些機制並列,扮演的是傳輸角色,而非任何一者的替代品。

解碼實作範例

為了把機制說明得更具體,這裡有一個完整的來回轉換範例,你可以用上面的字母表手工驗證。取 ASCII 文字 'f'——1 個位元組,0x66,二進位為 01100110。

  1. 在位元組後面補上 16 個零位元,把它擴成 24 位元:01100110 00000000 00000000。
  2. 切成 4 個 6 位元組:011001 100000 000000 000000。
  3. 把每一組轉成十進位索引:25、32、0、0。
  4. 在字母表中查詢每個索引:25 = 'Z'、32 = 'g'、0 = 'A'、0 = 'A'。
  5. 最後兩個字元是填充用的,因此改成填補字元:'Zg=='。

現在把 'Zg==' 解碼回來:讀字母表——Z=25、g=32、pad、pad。寫出 6 位元值:011001 100000。串接成 12 位元:011001100000。切成位元組:01100110 = 0x66 = 'f'。這就是原始的位元組。在線解碼器在微秒內就能完成這個過程,並能處理任意長度的輸入。

快速疑難排解

當解碼後的字串看起來幾乎正確,卻夾帶奇怪的字元時,請依序確認下列項目:

  • 字元集錯誤。標準 Base64 使用 '+' 與 '/';URL 安全版本則使用 '-' 與 '_'。若輸入來自 URL 或檔名,請先嘗試 URL 安全形式。
  • 填補字元被移除。某些傳輸方式(URL、JSON 欄位)會去除尾端的 '=' 符號。請將其補回,使長度為四的倍數。
  • 內嵌換行字元。MIME 換行格式的 Base64 每 76 個字元會有換行。大多數解碼器會自動去除;若您的解碼器未處理,請手動將其刪除。
  • 其實根本不是 Base64。Hex、Base32、Base58 與 Base100 乍看之下都很相似——只是字元集與規則不同。解碼前請先確認字元集。
  • UTF-8 編碼不符。若解碼後的位元組看起來像帶有變音符號的 Latin-1 亂碼,而您預期應為重音字元,則原始資料並非以 UTF-8 編碼。

延伸閱讀:Base64 與 Hex 轉換器:取得精確的 RFC 4648 位元組

延伸閱讀:二進位與文字對照速查表:ASCII 參考與範例