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

Java 中文字元轉 Unicode 與十六進制完整實作

     編輯:Java 相關知識

應用場景

  • 資料庫儲存特殊字元避免編碼問題
  • 網路傳輸協定要求 ASCII 安全字元
  • 日誌系統統一編碼格式
  • 前端 JavaScript \uXXXX 格式互轉

核心概念

完整工具類實作

import java.nio.charset.StandardCharsets;
import java.text.Normalizer;

public final class ChineseEncoder {

    private ChineseEncoder() {} // 工具類禁止實例化

    /**
     * 字串轉 Unicode Escape (\uXXXX)
     * @param input 原始字串
     * @return 轉換後字串,非 BMP 字元會產生雙代理對
     */
    public static String toUnicodeEscape(String input) {
        if (input == null) return null;
        StringBuilder sb = new StringBuilder(input.length() * 6);
        for (char c : input.toCharArray()) {
            if (c <= 0x7F && c != '\\') { // ASCII 可列印字元保持原樣 (可依需求調整)
                sb.append(c);
            } else {
                sb.append(String.format("\\u%04x", (int) c));
            }
        }
        return sb.toString();
    }

    /**
     * Unicode Escape 還原字串
     * @param escaped 含 \uXXXX 格式字串
     * @return 還原後字串
     */
    public static String fromUnicodeEscape(String escaped) {
        if (escaped == null) return null;
        StringBuilder sb = new StringBuilder();
        int i = 0;
        while (i < escaped.length()) {
            if (escaped.charAt(i) == '\\' && i + 1 < escaped.length() && escaped.charAt(i + 1) == 'u') {
                if (i + 5 < escaped.length()) {
                    try {
                        int code = Integer.parseInt(escaped.substring(i + 2, i + 6), 16);
                        sb.append((char) code);
                        i += 6;
                        continue;
                    } catch (NumberFormatException ignored) {}
                }
            }
            sb.append(escaped.charAt(i++));
        }
        return sb.toString();
    }

    /**
     * 字串轉 UTF-8 十六進制 (大寫,空格分隔)
     * @param input 原始字串
     * @return 如 "E4 B8 AD E6 96 87"
     */
    public static String toUtf8Hex(String input) {
        if (input == null) return null;
        byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0) sb.append(' ');
            sb.append(String.format("%02X", bytes[i] & 0xFF));
        }
        return sb.toString();
    }

    /**
     * UTF-8 Hex 還原字串
     * @param hex 如 "E4 B8 AD" 或 "E4B8AD"
     * @return 還原字串
     */
    public static String fromUtf8Hex(String hex) {
        if (hex == null) return null;
        String clean = hex.replaceAll("\\s+", "");
        if (clean.length() % 2 != 0) throw new IllegalArgumentException("Hex 長度需為偶數");
        byte[] bytes = new byte[clean.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(clean.substring(i * 2, i * 2 + 2), 16);
        }
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 字串轉 URL 編碼 (application/x-www-form-urlencoded)
     */
    public static String toUrlEncoded(String input) {
        try {
            return java.net.URLEncoder.encode(input, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String test = "中文測試123";
        System.out.println("原文: " + test);
        System.out.println("Unicode Escape: " + toUnicodeEscape(test));
        System.out.println("UTF-8 Hex: " + toUtf8Hex(test));
        System.out.println("URL Encoded: " + toUrlEncoded(test));
        System.out.println("--- 還原測試 ---");
        System.out.println(fromUnicodeEscape(toUnicodeEscape(test)));
        System.out.println(fromUtf8Hex(toUtf8Hex(test)));
    }
}

執行結果

原文: 中文測試123
Unicode Escape: \u4e2d\u6587\u6e2c\u8a66123
UTF-8 Hex: E4 B8 AD E6 96 87 E6 B8 AC E8 A9 A6 31 32 33
URL Encoded: %E4%B8%AD%E6%96%87%E6%B8%AC%E8%A9%A6123
--- 還原測試 ---
中文測試123
中文測試123

補充:處理 Emoji 與補充平面字元

Java char 為 UTF-16 代碼單元,補充平面字元 (如 Emoji 😀 U+1F600) 會佔用兩個 char (Surrogate Pair)。上方 toUnicodeEscape 會輸出 \ud83d\ude00。若需輸出單一 \U0001F600 格式,需使用 codePointAt 遍歷:

public static String toUnicodeEscapeFull(String input) {
    if (input == null) return null;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < input.length(); ) {
        int cp = input.codePointAt(i);
        if (cp <= 0x7F && cp != '\\') {
            sb.append((char) cp);
        } else if (cp <= 0xFFFF) {
            sb.append(String.format("\\u%04x", cp));
        } else {
            sb.append(String.format("\\U%08x", cp));
        }
        i += Character.charCount(cp);
    }
    return sb.toString();
}

效能建議

  • 大量轉換時預估長度初始化 StringBuilder 容量。
  • 避免在迴圈中建立大量臨時物件 (如 String.format),可手動拼接十六進制字元。
  • 使用 StandardCharsets.UTF_8 避免編碼查找開銷。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
編碼方式格式範例適用場景
Unicode Escape\u4e2d\u6587Java 原始碼、Properties 檔、JSON 序列化
UTF-8 HexE4 B8 AD E6 96 87URL 編碼、二進位協定、除錯檢視位元組