首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現 Base64 編解碼:原理詳解與生產級代碼實現

     編輯:Java 相關知識

Base64 編碼原理

Base64 將任意二進制數據編碼為 64 個可打印字符(A-Z, a-z, 0-9, +, /),常用於網絡傳輸、數據存儲。

  • 分組: 每 3 個字節(24 位)分為 4 組,每組 6 位。
  • 填充: 高 2 位補 0 擴展為 8 位(1 字節),對應查表字符。
  • 補齊: 輸入不足 3 字節時,用 = 補齊輸出至 4 的倍數長度。
輸入:  [字節1] [字節2] [字節3]  (共 24 位)
        aaaaaaaa bbbbbbbb cccccccc
拆分:  aaaaaa  aabbbbbb  bbbbcccc  cc cccccc
        (6位)   (6位)      (6位)    (6位)
查表:   字符1    字符2      字符3    字符4

完整 Java 實現(基於 Apache HttpClient 核心邏輯精簡)

public final class Base64Codec {
    private static final char[] ENCODE_TABLE = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    private static final byte[] DECODE_TABLE = new byte[128];
    static {
        Arrays.fill(DECODE_TABLE, (byte) -1);
        for (int i = 0; i < ENCODE_TABLE.length; i++) {
            DECODE_TABLE[ENCODE_TABLE[i]] = (byte) i;
        }
    }

    /** 編碼 byte[] -> String */
    public static String encode(byte[] data) {
        if (data == null) return null;
        int len = data.length;
        int outLen = (len + 2) / 3 * 4;
        char[] out = new char[outLen];
        int i = 0, op = 0;
        while (i < len) {
            int b1 = data[i++] & 0xFF;
            int b2 = (i < len) ? data[i++] & 0xFF : 0;
            int b3 = (i < len) ? data[i++] & 0xFF : 0;
            int triplet = (b1 << 16) | (b2 << 8) | b3;
            out[op++] = ENCODE_TABLE[(triplet >> 18) & 0x3F];
            out[op++] = ENCODE_TABLE[(triplet >> 12) & 0x3F];
            out[op++] = (i > len + 1) ? '=' : ENCODE_TABLE[(triplet >> 6) & 0x3F];
            out[op++] = (i > len) ? '=' : ENCODE_TABLE[triplet & 0x3F];
        }
        return new String(out);
    }

    /** 解碼 String -> byte[] */
    public static byte[] decode(String str) {
        if (str == null) return null;
        str = str.trim();
        if (str.length() % 4 != 0) throw new IllegalArgumentException("Invalid Base64 length");
        int pad = 0;
        if (str.endsWith("==")) pad = 2;
        else if (str.endsWith("=")) pad = 1;
        int len = (str.length() / 4) * 3 - pad;
        byte[] out = new byte[len];
        int ip = 0, op = 0;
        while (ip < str.length()) {
            int b1 = DECODE_TABLE[str.charAt(ip++)];
            int b2 = DECODE_TABLE[str.charAt(ip++)];
            int b3 = DECODE_TABLE[str.charAt(ip++)];
            int b4 = DECODE_TABLE[str.charAt(ip++)];
            if (b1 < 0 || b2 < 0 || b3 < 0 || b4 < 0) throw new IllegalArgumentException("Invalid char");
            int triplet = (b1 << 18) | (b2 << 12) | (b3 << 6) | b4;
            out[op++] = (byte) (triplet >> 16);
            if (op < len) out[op++] = (byte) (triplet >> 8);
            if (op < len) out[op++] = (byte) triplet;
        }
        return out;
    }
}

關鍵點解析

  • 位運算代替乘除:移位、掩碼效率極高。
  • 查表法:編碼用字符數組,解碼用 128 長度 byte 數組(ASCII 範圍)實現 O(1) 反查。
  • 邊界處理:& 0xFF 確保無符號右移;補齊邏輯嚴格按標準。
  • 輸入校驗:解碼時檢查長度、非法字符、填充位正確性。

生產環境建議

  • 優先使用 JDK 8+ 內置 java.util.Base64(Base64.getEncoder()/getDecoder()),經過高度優化且支持 MIME/URL 安全變體。
  • 若需兼容舊版本,推薦 Apache Commons Codec Base64 類。
  • 避免手工實現用於高性能場景,標準庫經過 JIT 深度優化(如使用 Intrinsics)。

常見坑點

  1. 字符集問題:字符串獲取字節時必須指定 StandardCharsets.UTF_8。
  2. 換行符:MIME 規範每 76 字符換行,傳輸前需確認是否需要去除。
  3. URL 安全變體:將 + 換為 -,/ 換為 _,去除填充 =。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved