子兮子兮 子兮子兮

No can, but will.

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

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

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

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

字符串转 Unicode 编码

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

Unicode 编码转字符串

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

使用方法

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

完整代码

  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}



我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=wh4u6zpyhe1d