Base64 是將二進制數據轉為可打印 ASCII 字符的編碼方案,廣泛用於郵件傳輸、URL 安全傳遞、數據嵌入等場景。本文從歷史動機出發,詳細推導編碼算法三種情況,分析填充規則,並總結工程應用場景。
早期郵件系統 (SMTP) 僅允許傳輸 7-bit ASCII 字符 (0-127)。非英語語言 (中文、日文等) 採用多字節編碼 (GBK、UTF-8),高位位元為 1 的字節在經過某些網關/路由器時會被強制置 0 或丟棄,導致數據損壞、亂碼。Base64 將任意二進制數據映射為 64 個可打印字符 (A-Z, a-z, 0-9, +, /),確保數據在僅支持 7-bit 通道的系統中完好傳輸。
Base64 以 3 個字節 (24 bits) 為一組,拆分為 4 個 6-bit 單元,每單元對應 64 字符表中一個字符。
3 bytes = 24 bits → 4 × 6 bits → 4 Base64 chars 字符表: A-Z (0-25), a-z (26-51), 0-9 (52-61), + (62), / (63)
輸入: [b1: 8bits] [b2: 8bits] [b3: 8bits]
↓ 重組為 4 個 6-bit 組
輸出: [c1: 6bits] [c2: 6bits] [c3: 6bits] [c4: 6bits]
每組前補 00 擴展為 8-bit 字節存儲/傳輸
輸入: [b1: 8bits] [b2: 8bits=0...] 拆分: [b1高6位] [b1低2位+b2高4位(=0)] [b2低4位(=0)+補0] [全0] 輸出: c1 c2 c3 = (最後兩組無效,用 == 填充)
輸入: [b1: 8bits] [b2: 8bits] [b3: 8bits=0...] 拆分: [b1高6位] [b1低2位+b2高4位] [b2低4位+b3高2位(=0)] [b3低6位(=0)] 輸出: c1 c2 c3 = (最後一組無效,用 = 填充)
= 數量確定原始數據長度:無 = → 3n 字節;一個 = → 3n+2 字節;兩個 = → 3n+1 字節。標準 Base64 包含 +、/、=,在 URL 參數中需轉義。RFC 4648 定義 URL 安全字符表:
+ → - (減號)/ → _ (下劃線)= (解碼時根據長度推斷)Java 8+ Base64.getUrlEncoder()/Decoder() 直接支持。
<img src="data:image/png;base64,iVBORw0KGgo..."/>,減少 HTTP 請求。// Java 8+ 標準 API String encoded = Base64.getEncoder().encodeToString(bytes); byte[] decoded = Base64.getDecoder().decode(encodedStr); // URL 安全 String urlSafe = Base64.getUrlEncoder().encodeToString(bytes); byte[] decoded = Base64.getUrlDecoder().decode(urlSafeStr); // 無填充 Base64.getEncoder().withoutPadding().encodeToString(bytes);
避坑:不要用 Base64 作為加密手段,它無任何保密性,僅是編碼。敏感數據必須加密 (AES/RSA) 後再 Base64 編碼傳輸。