項目中頻繁遇到:Base64 傳輸二進制、Hex 顯示字節、URL 編碼參數傳遞。統一封裝為無狀態工具類,屏蔽 JDK 版本差異 (Java 8 才有 java.util.Base64) 與第三方庫依賴。
public final class CodecUtils {
// ========== Base64 ==========
private static final Base64.Encoder B64_ENC = Base64.getEncoder();
private static final Base64.Decoder B64_DEC = Base64.getDecoder();
private static final Base64.Encoder B64_URL_ENC = Base64.getUrlEncoder(); // 無填充、URL安全
private static final Base64.Decoder B64_URL_DEC = Base64.getUrlDecoder();
public static String encodeBase64(byte[] data) {
return data == null ? null : B64_ENC.encodeToString(data);
}
public static String encodeBase64(String text, Charset charset) {
return text == null ? null : B64_ENC.encodeToString(text.getBytes(charset));
}
public static byte[] decodeBase64(String encoded) {
return encoded == null ? null : B64_DEC.decode(encoded);
}
public static String decodeBase64ToString(String encoded, Charset charset) {
byte[] bytes = decodeBase64(encoded);
return bytes == null ? null : new String(bytes, charset);
}
// URL 安全 Base64 (無 padding, +/ -> -_)
public static String encodeBase64Url(byte[] data) {
return data == null ? null : B64_URL_ENC.encodeToString(data);
}
public static byte[] decodeBase64Url(String encoded) {
return encoded == null ? null : B64_URL_DEC.decode(encoded);
}
// ========== Hex ==========
private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
public static String encodeHex(byte[] data) {
if (data == null) return null;
char[] chars = new char[data.length * 2];
for (int i = 0; i < data.length; i++) {
int b = data[i] & 0xFF;
chars[i * 2] = HEX_DIGITS[b >>> 4];
chars[i * 2 + 1] = HEX_DIGITS[b & 0x0F];
}
return new String(chars);
}
public static byte[] decodeHex(String hex) {
if (hex == null || hex.length() % 2 != 0) return null;
byte[] data = new byte[hex.length() / 2];
for (int i = 0; i < data.length; i++) {
int high = Character.digit(hex.charAt(i * 2), 16);
int low = Character.digit(hex.charAt(i * 2 + 1), 16);
if (high < 0 || low < 0) return null;
data[i] = (byte) ((high << 4) | low);
}
return data;
}
// ========== URL Encoding ==========
public static String encodeUrl(String value, Charset charset) {
try {
return value == null ? null : URLEncoder.encode(value, charset.name());
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
public static String decodeUrl(String value, Charset charset) {
try {
return value == null ? null : URLDecoder.decode(value, charset.name());
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
// ========== 便捷方法 ==========
public static String md5Hex(String input) { /* 見 MD5 文章 */ }
public static String sha256Hex(String input) { /* MessageDigest.getInstance("SHA-256") */ }
}
| 編碼 | 用途 | 字符集 | 長度膨脹 | 可讀性 | Java 版本 |
|---|---|---|---|---|---|
| Base64 標準 | 郵件附件、XML/JSON 嵌入二進制、Token 傳輸 | A-Z a-z 0-9 + / = | ~33% | 低 | JDK 8+ (舊版用 Apache Commons Codec) |
| Base64 URL | URL 參數、Cookie、Header、JWT | A-Z a-z 0-9 - _ (無 =) | ~33% | 低 | JDK 8+ |
| Hex | 調試輸出、密碼學摘要顯示、數據庫存儲字節 | 0-9 a-f | 100% | 高 | 所有版本 |
| URL Encoding | HTTP 表單參數、Query String | 保留字母數字、- _ . ~,其餘 %XX | 可變 | 中 | 所有版本 |
BASE64Encoder 輸出含換行,JDK 8 Base64.getEncoder() 不換行URLEncoder 將空格編為 +,URI.toASCIIString() 編為 %20,表單用前者,URL 路徑用後者Charset (推薦 StandardCharsets.UTF_8)IllegalArgumentException,建議捕獲返回 nullBase64 編碼: ~15 ms (JDK 內建原生優化) Base64 解碼: ~12 ms Hex 編碼: ~8 ms (簡單位運算) Hex 解碼: ~6 ms URL 編碼: ~25 ms (字符串處理開銷大)
編解碼是系統邊界的「翻譯官」,統一封裝 CodecUtils 可消除重複造輪子、版本兼容、字符集不一致等隱患。現代 Java (8+) 請直接使用 java.util.Base64、URLEncoder/Decoder、手寫 Hex,零第三方依賴、性能最優、維護最輕。