Java Unicode 编码和字符串互转,支持混合内容解码
- 字符串完全转 Unicode 编码
- 字符串转 Unicode 忽略半角
- 普通 Unicode 编码转字符串
- 混合 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));
}
}
(。・v・。)
喜欢这篇文章吗?欢迎分享到你的微博、QQ群,并关注我们的微博,谢谢支持。