使用方法
- 把要檢查的字串貼上到輸入框中。
- 檢視結論:是否有效、識別出的變體(標準或 URL 安全)以及解碼後的大小。
- 如果列出了問題,根據給出的位置找到無效字元、空白字元或位置不對的填充。
- 檢視識別出的內容型別,判斷資料是文字還是 PNG、PDF、ZIP 等檔案。
什麼樣的 Base64 才有效
- 字母表。只能包含
A-Z、a-z、0-9以及另外兩個字元:標準 Base64 是+和/,Base64URL 是-和_。如果一個字串同時出現了這兩組字元,通常是資料已損壞,或者由兩段不同來源的內容拼接而成。 - 填充。
=只能出現在末尾,且最多兩個。填充出現在中間,通常說明兩段編碼結果被直接拼在了一起。 - 長度。帶填充時,長度必須是 4 的整數倍。不帶填充時,除了 4n + 1 以外的長度都可以:單獨剩下的一個字元只有 6 位,湊不成一個位元組。
嚴格的解碼器還有一條規則:最後一個字元中未使用的低位必須為 0。很多解碼器會忽略這些位,但也有一些會直接拒絕,例如 Go 的 base64.StdEncoding.Strict()。
常見錯誤及解決方法
| 問題 | 常見原因 | 解決方法 |
|---|---|---|
| 無效字元 | 複製時連帶了引號、反斜槓,或 %2B、%3D 等轉義 | 刪除多餘字元,或先做 URL 解碼 |
| 中間有空格 | 經過 URL 或表單傳遞時 + 被轉成了空格 | 把 + 改回來,在 URL 中改用 Base64URL |
| 長度為 4n + 1 | 被列寬限制、日誌截斷或只複製了一部分 | 重新複製完整的值 |
| 填充在中間 | 兩段 Base64 被拼接在一起 | 拆開後分別解碼 |
| 含有換行 | MIME 或 PEM 格式的折行 | 一般無害;需要單行時刪除換行 |
有效不等於有意義
Base64 既沒有檔案頭也沒有校驗和,所謂有效只說明這個字串可以被解碼。很多普通單詞都能通過校驗,因為任意 4 個字母都能組成合法的一組。所以校驗工具還會實際解碼資料,並報告大小和內容型別。如果解碼出可讀文字,或者能識別出 PNG、PDF、ZIP 等檔案簽名,就基本可以確定它確實是 Base64;如果只得到幾個隨機位元組,則不然。想同時嘗試其他編碼,可以使用 編碼識別 工具。
在程式碼中校驗 Base64
// JavaScript:帶填充的標準 Base64(空字串也會匹配)
/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/
# Python:遇到無效字元時報錯,而不是跳過
import base64, binascii
try:
base64.b64decode(s, validate=True)
except binascii.Error:
print('invalid')
常見問題
為什麼普通單詞也被判定為有效 Base64?
因為它確實有效。只要由字母表中的字元組成且長度合適,就能解碼出一些位元組,例如單詞
test 會解碼成 3 個位元組。請檢視識別出的內容型別:如果結果既不是可讀文字,也不是已知的檔案型別,那麼輸入很可能本來就不是 Base64。帶空格或換行的 Base64 有效嗎?
MIME 和 PEM 會把 Base64 折成多行,大多數解碼器也會跳過空白字元。但 JSON 欄位、HTTP 頭、JWT 和 Data URI 都要求是一個連續的字串。校驗工具會單獨列出空白字元,方便你根據實際用途判斷是否需要處理。
沒有 = 填充的 Base64 有效嗎?
通常有效。Base64URL 一般不帶填充,RFC 4648 也允許在長度可由上下文確定時省略填充。不過有些嚴格的解碼器仍然要求填充,如果被拒絕,可以補上
= 使長度為 4 的整數倍。長度為 4n + 1 的無填充字串永遠無效。在 JavaScript 中如何判斷字串是不是 Base64?
如果要嚴格校驗帶填充的 Base64,可以用正規表示式匹配「若干組 4 個字母表字元,末尾可帶填充」的格式;更簡便的做法是把
atob() 放在 try/catch 中呼叫。注意,atob() 遇到無效輸入會丟擲 InvalidCharacterError,但會默默接受空白字元和缺失的填充,而且不接受 URL 安全字元。