子兮子兮 子兮子兮

No can, but will.

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

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

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

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

字符串转 Unicode 编码

 1
 2    /**
 3     * 字符串转 Unicode 编码
 4     *
 5     * @param string   原字符串
 6     * @param halfWith 是否转换半角字符
 7     * @return 编码后的字符串
 8     */
 9    public static String strToUnicode(String string, boolean halfWith) {
10        if (string == null || string.isEmpty()) {
11            // 传入字符串为空返回原内容
12            return string;
13        }
14
15        StringBuilder value = new StringBuilder(string.length() << 3);
16        String prefix = "\\u", zerofix = "0", unicode;
17        char c;
18        for (int i = 0, j; i < string.length(); i++) {
19            c = string.charAt(i);
20            if (!halfWith && c > 31 && c < 127) {
21                // 不转换半角字符
22                value.append(c);
23                continue;
24            }
25            value.append(prefix);
26
27            // 高 8 位
28            j = c >>> 8;
29            unicode = Integer.toHexString(j);
30            if (unicode.length() == 1) {
31                value.append(zerofix);
32            }
33            value.append(unicode);
34
35            // 低 8 位
36            j = c & 0xFF;
37            unicode = Integer.toHexString(j);
38            if (unicode.length() == 1) {
39                value.append(zerofix);
40            }
41            value.append(unicode);
42        }
43
44        return value.toString();
45    }
46

Unicode 编码转字符串

 1
 2    /**
 3     * Unicode 编码转字符串
 4     * 
 5     * @param string 支持 Unicode 编码和普通字符混合的字符串
 6     * @return 解码后的字符串
 7     */
 8    public static String unicodeToStr(String string) {
 9        String prefix = "\\u";
10        if (string == null || string.indexOf(prefix) < 0) {
11            // 传入字符串为空或不包含 Unicode 编码返回原内容
12            return string;
13        }
14
15        StringBuilder value = new StringBuilder(string.length() >> 2);
16        String[] strings = string.split("\\\\u");
17        String hex, mix;
18        char hexChar;
19        int ascii, n;
20
21        if (strings[0].length() > 0) {
22            // 处理开头的普通字符串
23            value.append(strings[0]);
24        }
25
26        try {
27            for (int i = 1; i < strings.length; i++) {
28                hex = strings[i];
29                if (hex.length() > 3) {
30                    mix = "";
31                    if (hex.length() > 4) {
32                        // 处理 Unicode 编码符号后面的普通字符串
33                        mix = hex.substring(4, hex.length());
34                    }
35                    hex = hex.substring(0, 4);
36
37                    try {
38                        Integer.parseInt(hex, 16);
39                    } catch (Exception e) {
40                        // 不能将当前 16 进制字符串正常转换为 10 进制数字,拼接原内容后跳出
41                        value.append(prefix).append(strings[i]);
42                        continue;
43                    }
44
45                    ascii = 0;
46                    for (int j = 0; j < hex.length(); j++) {
47                        hexChar = hex.charAt(j);
48                        // 将 Unicode 编码中的 16 进制数字逐个转为 10 进制
49                        n = Integer.parseInt(String.valueOf(hexChar), 16);
50                        // 转换为 ASCII 码
51                        ascii += n * ((int) Math.pow(16, (hex.length() - j - 1)));
52                    }
53
54                    // 拼接解码内容
55                    value.append((char) ascii).append(mix);
56                } else {
57                    // 不转换特殊长度的 Unicode 编码
58                    value.append(prefix).append(hex);
59                }
60            }
61        } catch (Exception e) {
62            // Unicode 编码格式有误,解码失败
63            return null;
64        }
65
66        return value.toString();
67    }
68

使用方法

 1
 2    /**
 3     * TEST METHOD
 4     * 
 5     * @param args cmd line arguments
 6     */
 7    public static void main(String[] args) {
 8        System.out.println(String.join("", "【", String.valueOf((char) 0), "】"));
 9        String str = "中英文混合字符串:子兮子兮 zixizixi.cn";
10        System.out.printf("【字符串内容】%s\n", str);
11
12        // 将字符串完全编码,第二个参数传 true
13        String unicode = strToUnicode(str, true);
14        System.out.printf("【字符串编码】%s\n", unicode);
15        System.out.printf("【字符串解码】%s\n\n", unicodeToStr(unicode));
16
17        unicode = "Unicode 混合字符串:【" + unicode + "】Unicode 混合字符串【" + unicode + "】Unicode 混合字符串!";
18        System.out.printf("【混合串内容】%s\n", unicode);
19        System.out.printf("【混合串解码】%s\n\n", unicodeToStr(unicode));
20        
21        // 要对混合串的编码进行一次性解码,第二个参数传 false
22        unicode = strToUnicode(unicode, false);
23        System.out.printf("【混合串编码】%s\n", unicode);
24        System.out.printf("【混合串解码】%s\n", unicodeToStr(unicode));
25    }
26

完整代码

  1package default;
  2
  3/**
  4 * Unicode 编解码工具类
  5 *
  6 * @author zixizixi.cn
  7 * @since 2019-11-11
  8 */
  9public final class UnicodeUtils {
 10
 11    /**
 12     * 字符串转 Unicode 编码
 13     *
 14     * @param string   原字符串
 15     * @param halfWith 是否转换半角字符
 16     * @return 编码后的字符串
 17     */
 18    public static String strToUnicode(String string, boolean halfWith) {
 19        if (string == null || string.isEmpty()) {
 20            // 传入字符串为空返回原内容
 21            return string;
 22        }
 23
 24        StringBuilder value = new StringBuilder(string.length() << 3);
 25        String prefix = "\\u", zerofix = "0", unicode;
 26        char c;
 27        for (int i = 0, j; i < string.length(); i++) {
 28            c = string.charAt(i);
 29            if (!halfWith && c > 31 && c < 127) {
 30                // 不转换半角字符
 31                value.append(c);
 32                continue;
 33            }
 34            value.append(prefix);
 35
 36            // 高 8 位
 37            j = c >>> 8;
 38            unicode = Integer.toHexString(j);
 39            if (unicode.length() == 1) {
 40                value.append(zerofix);
 41            }
 42            value.append(unicode);
 43
 44            // 低 8 位
 45            j = c & 0xFF;
 46            unicode = Integer.toHexString(j);
 47            if (unicode.length() == 1) {
 48                value.append(zerofix);
 49            }
 50            value.append(unicode);
 51        }
 52
 53        return value.toString();
 54    }
 55
 56    /**
 57     * Unicode 编码转字符串
 58     * 
 59     * @param string 支持 Unicode 编码和普通字符混合的字符串
 60     * @return 解码后的字符串
 61     */
 62    public static String unicodeToStr(String string) {
 63        String prefix = "\\u";
 64        if (string == null || string.indexOf(prefix) < 0) {
 65            // 传入字符串为空或不包含 Unicode 编码返回原内容
 66            return string;
 67        }
 68
 69        StringBuilder value = new StringBuilder(string.length() >> 2);
 70        String[] strings = string.split("\\\\u");
 71        String hex, mix;
 72        char hexChar;
 73        int ascii, n;
 74
 75        if (strings[0].length() > 0) {
 76            // 处理开头的普通字符串
 77            value.append(strings[0]);
 78        }
 79
 80        try {
 81            for (int i = 1; i < strings.length; i++) {
 82                hex = strings[i];
 83                if (hex.length() > 3) {
 84                    mix = "";
 85                    if (hex.length() > 4) {
 86                        // 处理 Unicode 编码符号后面的普通字符串
 87                        mix = hex.substring(4, hex.length());
 88                    }
 89                    hex = hex.substring(0, 4);
 90
 91                    try {
 92                        Integer.parseInt(hex, 16);
 93                    } catch (Exception e) {
 94                        // 不能将当前 16 进制字符串正常转换为 10 进制数字,拼接原内容后跳出
 95                        value.append(prefix).append(strings[i]);
 96                        continue;
 97                    }
 98
 99                    ascii = 0;
100                    for (int j = 0; j < hex.length(); j++) {
101                        hexChar = hex.charAt(j);
102                        // 将 Unicode 编码中的 16 进制数字逐个转为 10 进制
103                        n = Integer.parseInt(String.valueOf(hexChar), 16);
104                        // 转换为 ASCII 码
105                        ascii += n * ((int) Math.pow(16, (hex.length() - j - 1)));
106                    }
107
108                    // 拼接解码内容
109                    value.append((char) ascii).append(mix);
110                } else {
111                    // 不转换特殊长度的 Unicode 编码
112                    value.append(prefix).append(hex);
113                }
114            }
115        } catch (Exception e) {
116            // Unicode 编码格式有误,解码失败
117            return null;
118        }
119
120        return value.toString();
121    }
122
123    /**
124     * TEST METHOD
125     * 
126     * @param args cmd line arguments
127     */
128    public static void main(String[] args) {
129        System.out.println(String.join("", "【", String.valueOf((char) 0), "】"));
130        String str = "中英文混合字符串:子兮子兮 zixizixi.cn";
131        System.out.printf("【字符串内容】%s\n", str);
132
133        // 将字符串完全编码,第二个参数传 true
134        String unicode = strToUnicode(str, true);
135        System.out.printf("【字符串编码】%s\n", unicode);
136        System.out.printf("【字符串解码】%s\n\n", unicodeToStr(unicode));
137
138        unicode = "Unicode 混合字符串:【" + unicode + "】Unicode 混合字符串【" + unicode + "】Unicode 混合字符串!";
139        System.out.printf("【混合串内容】%s\n", unicode);
140        System.out.printf("【混合串解码】%s\n\n", unicodeToStr(unicode));
141        
142        // 要对混合串的编码进行一次性解码,第二个参数传 false
143        unicode = strToUnicode(unicode, false);
144        System.out.printf("【混合串编码】%s\n", unicode);
145        System.out.printf("【混合串解码】%s\n", unicodeToStr(unicode));
146    }
147
148}