什麼是 Base64?
Base64 是 1980 年代為 email 附件設計的編碼方式(RFC 4648),把任何「二進位資料」用 64 個 ASCII 可印字元(A-Z、a-z、0-9、+、/)重新表示。原意是讓二進位檔案能在「只接受純文字」的系統(如早期 SMTP email、HTTP headers)中安全傳輸,不被換行、空白、控制字元破壞。
今日 Base64 幾乎無所不在:email 附件(MIME)、JWT token、HTTP Basic Auth、Data URL(把圖片塞進 HTML / CSS)、API 傳檔(圖片轉 Base64 放進 JSON)。
Base64 把每 3 個位元組編成 4 個字元,長度會變成原來的約 4/3 倍(增加 33%)。這是設計使然——犧牲體積換取「能在純文字環境傳輸」。
如果原本資料不是 3 的倍數,結尾會補 =(padding)讓總長度是 4 的倍數。這就是為什麼 Base64 字串常以一個或兩個 = 結尾。
瀏覽器內建的 btoa() 碰到第一個中文字就會壞,因為它把字串裡的每個字元都當成一個位元組,超過 U+00FF 的字元一律丟出 InvalidCharacterError;中文、日文、韓文與 emoji 全部中槍。反方向的 atob() 回傳的是原始位元組,直接顯示就會得到「café 變成 café」那種亂碼。這頁進去先過 TextEncoder、出來再過 TextDecoder,所以中文與 emoji 來回一趟不會壞。
什麼時候會用到,又該用哪個變體
- JWT decode:JWT 的 header / payload 是 Base64 編碼,貼進來可看欄位內容
- HTTP Basic Auth:
Authorization: Basic dXNlcjpwYXNz解開就是user:pass - Data URL:把小圖直接寫進 HTML / CSS,減少 HTTP request,用圖片轉 Base64 工具更方便
- API 傳輸二進位:JSON 不能放 binary,用 Base64 包進去 string 欄位
- 看不明訊息:log 或網址中看到「
SGVsbG8gV29ybGQ=」這種感覺像密碼的字串,解碼看看是不是普通文字
字母表則要看它最後要待在哪裡:
- 標準 Base64(RFC 4648 §4):用
+/,結尾=padding。本工具預設此種 - URL-safe Base64(RFC 4648 §5):把
+換-、/換_,避免在 URL 中需要再 escape。JWT 用這種;編碼時勾「URL-safe」就會輸出這種 - 無 padding 版本:省略結尾
=,JWT 也常用。本頁的 URL-safe 輸出就不補= - Base32 / Base16(HEX):類似概念,字元集更小,用於特殊情境(OTP 密鑰常用 Base32)
email 內文用的是 MIME 版本(RFC 2045):同一套標準字母表,但每 76 個字元折一行,PEM 憑證區塊則是每 64 個字元折一行,解碼器本來就該忽略這些換行。如果你要做的只是把文字塞進網址、而不是搬運二進位資料,那要的其實是百分比編碼,請用網址編碼工具。
怎麼做出 HTTP Basic Auth 標頭
- 模式留在「文字 → Base64」。
- 輸入帳號、一個半形冒號、密碼,冒號前後都不要空格。第一個冒號是分隔點,所以密碼裡可以有冒號,帳號裡不行。
- 按「複製」,標頭寫成
Authorization: Basic後面空一格再接編碼結果。 - 把結果切回「Base64 → 文字」解一次確認。如果這串是在終端機產生的,標頭看起來明明沒錯卻一直 401,兇手通常是 echo 多補的換行。
這個標頭等於把帳密攤在明面上,任何攔得到請求的人都能還原,所以 Basic Auth 只能走 HTTPS。多數 HTTP 客戶端會幫你組好,例如 curl -u user:password。
解開在 log 或網址裡撿到的字串
- 切到「Base64 → 文字」貼上。貼進來解不開,最常見的原因是把前後的引號或結尾的逗號一起複製了,先修掉再試。
- 字串裡出現
-或_,那是 URL-safe 版本。不用自己換字元,本頁會照 base64url 解,結果下方也會註明;缺了結尾的=也會自動補上。 - 解出來有 � 或看不懂的中文,原文多半不是 UTF-8。台灣舊系統(早期網頁、銀行與政府資料)常用 Big5,把「解碼字元集」切到 Big5 再看一次。
- 字串中間有兩個點,你拿到的是 JWT 而不是單一段 Base64。交給JWT 解碼工具,它會幫你切段並處理 URL-safe 字母表。
- 解出來是一堆符號而不是錯誤訊息,代表那些位元組本來就不是文字:壓縮過的內容、圖片或加密結果都會乾淨地解開,看起來仍然像雜訊。
- 解出來是 JSON,就貼到JSON 格式化工具看結構,順便驗語法。
結果怎麼帶到該去的地方
輸出是不換行的一整串,這正是標頭、JSON 欄位與環境變數要的形狀。畫面上會自動折行顯示,看起來像好幾行,複製下來仍然是一整串。
- 貼進 JSON:直接當字串值貼。Base64 的字元都不需要跳脫,所以不會冒出反斜線。
- 貼進網址:標準 Base64 不是網址安全的。要嘛整串百分比編碼(
+變%2B、/變%2F、=變%3D),要嘛編碼時勾「URL-safe」改用 base64url 再貼。 - 貼進 YAML 或設定檔:保持單行,並把編輯器「長行自動折行後寫回檔案」的設定關掉;被插進去的換行會改變這個值。
中文怎麼處理?各語言與命令列的差異
本工具用 UTF-8 編碼中文,與現代瀏覽器、Node.js、Python 3、Go 預設行為一致。一個中文字通常編成 3 個位元組,Base64 後變成 4 字元。
如果解碼後出現亂碼,通常是來源用了非 UTF-8 編碼(早期 Big5、GB2312 系統)。Base64 本身只規範「位元組到字元的對應」,不規範「位元組對應什麼字元集」。台灣舊系統的 Big5 資料,把上方的「解碼字元集」切到 Big5 就解得回來;GB2312 本頁不支援。
每個平台都內建 Base64,差別在預設值:用哪套字母表、寫不寫 padding、長輸出折不折行、解碼器嚴不嚴格。瀏覽器的 btoa() 與 atob() 只處理位元組,UTF-8 那一段要自己接:
const b64 = btoa(String.fromCharCode(...new TextEncoder().encode(text)))
const text = new TextDecoder().decode(
Uint8Array.from(atob(b64), c => c.charCodeAt(0)),
)Node.js 把位元組處理藏在 Buffer 裡,另外提供 base64url 這個編碼名稱,直接換成 URL-safe 字母表並去掉 padding:
Buffer.from(text, 'utf8').toString('base64')
Buffer.from(b64, 'base64').toString('utf8')
Buffer.from(text, 'utf8').toString('base64url')Python 3 兩端都是 bytes,所以 b64encode 回傳的是 bytes 不是字串;URL-safe 是另一組函式,而且解碼器預設會忽略不認識的字元,要嚴格就傳 validate=True:
import base64
base64.b64encode(text.encode()).decode()
base64.b64decode(b64, validate=True).decode()
base64.urlsafe_b64encode(text.encode()).decode()PHP 的字串本來就是位元組串,base64_encode() 與 base64_decode() 直接吃字串,UTF-8 中文不用另外轉;但檔案若是 Big5 存的,編出來的就是 Big5 位元組,解碼端照 UTF-8 讀一樣會是亂碼。Go 則把選擇攤開成 encoding/base64 的四種:StdEncoding 與 URLEncoding 寫 padding,RawStdEncoding 與 RawURLEncoding 不寫。
命令列是經典地雷區。echo 會多加一個換行,那個換行會被一起編進去,做出伺服器不認的憑證,所以要用 printf。GNU coreutils 還會在 76 欄折行,除非你關掉:
printf '%s' 'user:password' | base64 -w 0 # GNU,不折行
printf '%s' 'user:password' | base64 # macOS,預設就不折行
printf '%s' 'dXNlcjpwYXNz' | base64 -d # 解碼macOS 上的是 BSD 版本,沒有 -w;它長年接受 -D 解碼,較新的版本也收 -d,寫進腳本前先跑一次 base64 --help 確認。資料庫也有:PostgreSQL 的 encode 與 decode、MySQL 的 TO_BASE64() 與 FROM_BASE64(),兩邊預設都會把長輸出折成多行,從查詢結果撈出來的值可能要先把換行去掉。
限制與隱私
不會離開你的瀏覽器。轉換用 TextEncoder、TextDecoder 與內建的 btoa()、atob() 在本機完成,輸入不上傳、不儲存、不記錄,結果區也對錄影分析做了遮罩。即使如此,正式環境的憑證還是建議用本機指令處理:貼進任何網頁的活憑證,就是去過一個它本來不需要去的地方。
它不是安全機制,也不是壓縮。沒有金鑰所以沒有機密性,沒有檢查碼所以被改過的字串多半還是解得開。讀得懂 JWT 的 payload 只代表你知道它宣稱了什麼,不代表那是真的,那要驗簽章才算數。體積還會多出約三分之一,內嵌成 Data URL 的圖片沒辦法單獨被快取,嚴格的 CSP 也可能直接擋掉。
這個解碼器吃什麼、不吃什麼。解碼前會先去掉空白與換行,所以 MIME 折行的區塊照樣解得開;URL-safe 的 - 與 _ 會先換回標準字元,缺的 = 會補上,再交給瀏覽器照 WHATWG Infra 標準的 forgiving-base64 演算法解。長度除以 4 餘 1 的字串補不回來,會直接顯示錯誤。
檔案大小。整串是一次轉完的,幾 MB 的文字會讓分頁頓住,檔案等級的請改用上面的命令列。
常見問題
Base64 是加密嗎?
不是。Base64 是「編碼」(任何人都能 decode,無 key),不是「加密」(需 key 才能 decrypt)。用 Base64 包密碼或私鑰不會增加安全性,只是讓人看不懂表面字。真正要保密請用 AES 等加密演算法。
為什麼解碼失敗?
這個解碼器會先去掉空白與換行,缺了結尾的 = 會自動補上,URL-safe 的 - 與 _ 也直接認得,所以真正會失敗的只有兩種:(1)去掉空白後長度除以 4 餘 1,通常是少複製了一段;(2)夾了其他不屬於 Base64 的符號,例如連引號或逗號一起複製了。解得開但看到亂碼不算失敗,那是原文不是 UTF-8;台灣舊系統的資料多半是 Big5,把「解碼字元集」切到 Big5 再看一次。
Base64 可以壓縮資料嗎?
不行,反而會更大。Base64 是編碼,會讓資料長 33%。要壓縮用 gzip / brotli,不是 Base64。
標準 Base64 跟 URL-safe 差在哪?JWT 為什麼沒有結尾的等號?
RFC 4648 第 4 節的標準字母表用 + 與 /,第 5 節的 URL-safe 版本把它們換成 - 與 _,其餘完全一樣。會需要換是因為網址裡的 / 有自己的意思,而 + 在查詢字串裡會被讀成空格。JWT 用的就是 URL-safe 字母表,而且把結尾的 = 拿掉,所以 JWT 的每一段幾乎不會以等號結尾。很多標準解碼器遇到 - 或 _ 會直接失敗;本頁解碼兩種字母表都吃,編碼時勾「URL-safe」就會輸出 base64url 並去掉結尾的 =。
用命令列做出來的 Basic Auth 標頭,為什麼伺服器一直回 401?
最常見的原因是 echo 自動補的換行被一起編進去了,改用 printf '%s' 'user:password' | base64 就沒事。另外 GNU coreutils 的 base64 預設會在 76 個字元處折行,要加 -w 0 才不折;macOS 內建的是 BSD 版本,沒有 -w,預設就不折行。把疑似有問題的字串貼回本頁解碼,看結尾是不是多了一個換行,是最快的確認方式。
資料來源
- IETF,RFC 4648:Base16、Base32、Base64 資料編碼(§4 標準字母表、§5 網址與檔名安全字母表,以及 padding 規則)。
- IETF,RFC 2045:MIME 第一部(email 內文的 Base64,含每行 76 字元上限)。
- IETF,RFC 7519:JSON Web Token(JWT 各段為何用去掉 padding 的 URL-safe Base64)。
- MDN,Base64(瀏覽器 API、
btoa()的 Unicode 問題,以及本頁採用的TextEncoder解法)。 - WHATWG,Infra 標準的 forgiving-base64 decode(
atob()究竟接受與拒絕哪些輸入)。 - Node.js 的
Buffer、Python 的base64模組、Go 的encoding/base64、PHP 的字串函式,以及 PostgreSQL 與 MySQL 的字串函式文件,涵蓋上面提到的各平台行為;各家都可能改預設值,請以你正在用的版本為準。
相關工具
- URL 編碼解碼
URL 編碼解碼:中文與特殊字元的百分比編碼雙向轉換,支援 encodeURI 與 encode…
- JSON 格式化
JSON 美化與壓縮雙向轉換,支援 2 / 4 / Tab 縮排,語法錯誤即時標出行號。
- JWT Decode 解碼
JWT 解碼工具:貼上 JSON Web Token 解出 header 與 payload,過…
- 雜湊計算
計算文字與檔案的 SHA-1、SHA-256、SHA-384、SHA-512 雜湊值,走瀏覽器原…
- 圖片轉 Base64
上傳圖片即時轉成 Base64 字串(含 Data URL 格式),直接貼進 HTML、CSS、…
- UUID 產生器
產生 UUID v4(隨機)與 UUID v7(含時間戳排序)通用唯一識別碼,支援批量產生與一鍵複製。
- Regex 正規表示式測試
輸入 regex pattern 與測試文字,即時標出所有匹配結果、捕獲分組與位置,支援 g、i、m、s、u、y 旗標。
隱私:編碼與解碼全部在你的瀏覽器裡用 TextEncoder、TextDecoder 與 btoa()、atob() 完成,輸入不會送到伺服器、不會儲存也不會記錄,頁面上的結果另外對錄影分析做了遮罩。分析只知道這一頁被看過。
