子兮子兮 子兮子兮

子兮子兮风兮寒,三江七泽情洄沿。

目录
Java 版 Unicode 编码和字符串互转,支持混合内容解码
/        

Java 版 Unicode 编码和字符串互转,支持混合内容解码

通过 Java 在不依赖三方包的情况下实现以下效果:

  1. 字符串完全转 Unicode 编码
  2. 字符串转 Unicode 忽略半角
  3. 普通 Unicode 编码转字符串
  4. 混合 Unicode 编码转字符串

字符串转 Unicode 编码

/**
     * 字符串转 Unicode 编码
     *
     * @param string   原字符串
     * @param halfWith 是否转换半角字符
     * @return 编码后的字符串
     */
    public static String strToUnicode(String string, boolean halfWith) {
        if (string == null || string.isEmpty()) {
            // 传入字符串为空返回原内容
            return string;
        }

        StringBuilder value = new StringBuilder(string.length() << 3);
        String prefix = "\\u", zerofix = "0", unicode;
        char c;
        for (int i = 0, j; i < string.length(); i++) {
            c = string.charAt(i);
            if (!halfWith && c > 31 && c < 127) {
                // 不转换半角字符
                value.append(c);
                continue;
            }
            value.append(prefix);

            // 高 8 位
            j = c >>> 8;
            unicode = Integer.toHexString(j);
            if (unicode.length() == 1) {
                value.append(zerofix);
            }
            value.append(unicode);

            // 低 8 位
            j = c & 0xFF;
            unicode = Integer.toHexString(j);
            if (unicode.length() == 1) {
                value.append(zerofix);
            }
            value.append(unicode);
        }

        return value.toString();
    }

Unicode 编码转字符串

/**
     * Unicode 编码转字符串
     * 
     * @param string 支持 Unicode 编码和普通字符混合的字符串
     * @return 解码后的字符串
     */
    public static String unicodeToStr(String string) {
        String prefix = "\\u";
        if (string == null || string.indexOf(prefix) < 0) {
            // 传入字符串为空或不包含 Unicode 编码返回原内容
            return string;
        }

        StringBuilder value = new StringBuilder(string.length() >> 2);
        String[] strings = string.split("\\\\u");
        String hex, mix;
        char hexChar;
        int ascii, n;

        if (strings[0].length() > 0) {
            // 处理开头的普通字符串
            value.append(strings[0]);
        }

        try {
            for (int i = 1; i < strings.length; i++) {
                hex = strings[i];
                if (hex.length() > 3) {
                    mix = "";
                    if (hex.length() > 4) {
                        // 处理 Unicode 编码符号后面的普通字符串
                        mix = hex.substring(4, hex.length());
                    }
                    hex = hex.substring(0, 4);

                    try {
                        Integer.parseInt(hex, 16);
                    } catch (Exception e) {
                        // 不能将当前 16 进制字符串正常转换为 10 进制数字,拼接原内容后跳出
                        value.append(prefix).append(strings[i]);
                        continue;
                    }

                    ascii = 0;
                    for (int j = 0; j < hex.length(); j++) {
                        hexChar = hex.charAt(j);
                        // 将 Unicode 编码中的 16 进制数字逐个转为 10 进制
                        n = Integer.parseInt(String.valueOf(hexChar), 16);
                        // 转换为 ASCII 码
                        ascii += n * ((int) Math.pow(16, (hex.length() - j - 1)));
                    }

                    // 拼接解码内容
                    value.append((char) ascii).append(mix);
                } else {
                    // 不转换特殊长度的 Unicode 编码
                    value.append(prefix).append(hex);
                }
            }
        } catch (Exception e) {
            // Unicode 编码格式有误,解码失败
            return null;
        }

        return value.toString();
    }

使用方法

/**
     * TEST METHOD
     * 
     * @param args cmd line arguments
     */
    public static void main(String[] args) {
        System.out.println(String.join("", "【", String.valueOf((char) 0), "】"));
        String str = "中英文混合字符串:子兮子兮 zixizixi.cn";
        System.out.printf("【字符串内容】%s\n", str);

        // 将字符串完全编码,第二个参数传 true
        String unicode = strToUnicode(str, true);
        System.out.printf("【字符串编码】%s\n", unicode);
        System.out.printf("【字符串解码】%s\n\n", unicodeToStr(unicode));

        unicode = "Unicode 混合字符串:【" + unicode + "】Unicode 混合字符串【" + unicode + "】Unicode 混合字符串!";
        System.out.printf("【混合串内容】%s\n", unicode);
        System.out.printf("【混合串解码】%s\n\n", unicodeToStr(unicode));
        
        // 要对混合串的编码进行一次性解码,第二个参数传 false
        unicode = strToUnicode(unicode, false);
        System.out.printf("【混合串编码】%s\n", unicode);
        System.out.printf("【混合串解码】%s\n", unicodeToStr(unicode));
    }

完整代码

package default;

/**
 * Unicode 编解码工具类
 *
 * @author zixizixi.cn
 * @since 2019-11-11
 */
public final class UnicodeUtils {

    /**
     * 字符串转 Unicode 编码
     *
     * @param string   原字符串
     * @param halfWith 是否转换半角字符
     * @return 编码后的字符串
     */
    public static String strToUnicode(String string, boolean halfWith) {
        if (string == null || string.isEmpty()) {
            // 传入字符串为空返回原内容
            return string;
        }

        StringBuilder value = new StringBuilder(string.length() << 3);
        String prefix = "\\u", zerofix = "0", unicode;
        char c;
        for (int i = 0, j; i < string.length(); i++) {
            c = string.charAt(i);
            if (!halfWith && c > 31 && c < 127) {
                // 不转换半角字符
                value.append(c);
                continue;
            }
            value.append(prefix);

            // 高 8 位
            j = c >>> 8;
            unicode = Integer.toHexString(j);
            if (unicode.length() == 1) {
                value.append(zerofix);
            }
            value.append(unicode);

            // 低 8 位
            j = c & 0xFF;
            unicode = Integer.toHexString(j);
            if (unicode.length() == 1) {
                value.append(zerofix);
            }
            value.append(unicode);
        }

        return value.toString();
    }

    /**
     * Unicode 编码转字符串
     * 
     * @param string 支持 Unicode 编码和普通字符混合的字符串
     * @return 解码后的字符串
     */
    public static String unicodeToStr(String string) {
        String prefix = "\\u";
        if (string == null || string.indexOf(prefix) < 0) {
            // 传入字符串为空或不包含 Unicode 编码返回原内容
            return string;
        }

        StringBuilder value = new StringBuilder(string.length() >> 2);
        String[] strings = string.split("\\\\u");
        String hex, mix;
        char hexChar;
        int ascii, n;

        if (strings[0].length() > 0) {
            // 处理开头的普通字符串
            value.append(strings[0]);
        }

        try {
            for (int i = 1; i < strings.length; i++) {
                hex = strings[i];
                if (hex.length() > 3) {
                    mix = "";
                    if (hex.length() > 4) {
                        // 处理 Unicode 编码符号后面的普通字符串
                        mix = hex.substring(4, hex.length());
                    }
                    hex = hex.substring(0, 4);

                    try {
                        Integer.parseInt(hex, 16);
                    } catch (Exception e) {
                        // 不能将当前 16 进制字符串正常转换为 10 进制数字,拼接原内容后跳出
                        value.append(prefix).append(strings[i]);
                        continue;
                    }

                    ascii = 0;
                    for (int j = 0; j < hex.length(); j++) {
                        hexChar = hex.charAt(j);
                        // 将 Unicode 编码中的 16 进制数字逐个转为 10 进制
                        n = Integer.parseInt(String.valueOf(hexChar), 16);
                        // 转换为 ASCII 码
                        ascii += n * ((int) Math.pow(16, (hex.length() - j - 1)));
                    }

                    // 拼接解码内容
                    value.append((char) ascii).append(mix);
                } else {
                    // 不转换特殊长度的 Unicode 编码
                    value.append(prefix).append(hex);
                }
            }
        } catch (Exception e) {
            // Unicode 编码格式有误,解码失败
            return null;
        }

        return value.toString();
    }

    /**
     * TEST METHOD
     * 
     * @param args cmd line arguments
     */
    public static void main(String[] args) {
        System.out.println(String.join("", "【", String.valueOf((char) 0), "】"));
        String str = "中英文混合字符串:子兮子兮 zixizixi.cn";
        System.out.printf("【字符串内容】%s\n", str);

        // 将字符串完全编码,第二个参数传 true
        String unicode = strToUnicode(str, true);
        System.out.printf("【字符串编码】%s\n", unicode);
        System.out.printf("【字符串解码】%s\n\n", unicodeToStr(unicode));

        unicode = "Unicode 混合字符串:【" + unicode + "】Unicode 混合字符串【" + unicode + "】Unicode 混合字符串!";
        System.out.printf("【混合串内容】%s\n", unicode);
        System.out.printf("【混合串解码】%s\n\n", unicodeToStr(unicode));
        
        // 要对混合串的编码进行一次性解码,第二个参数传 false
        unicode = strToUnicode(unicode, false);
        System.out.printf("【混合串编码】%s\n", unicode);
        System.out.printf("【混合串解码】%s\n", unicodeToStr(unicode));
    }

}