应用: 在文本编辑器中表情包通常使用UTF16编码进行表示
注意: Java中并不能直接打印Unicode编码的内容,需要转成UTF16编码才可以
原理
//1个unicode编码实际值大于4位16进制数 == 转化成两个UTF16编码 【笑脸表强包Unicode编码:1F600】
1. 将 Unicode 编码的值减去 0x10000,得到一个 20 位的二进值 == 不够20位,则左侧补0
笑脸:F600 ==> 二进制:00001 11101 10000 00000
2. 将这个 20 位的值分成两个 10 位的部分,分别称为高位部分和低位部分。
高位:00001 11101 低位:10000 00000
3. 将高位部分加上 0xD800 得到第一个 16 位的编码单元,即 UTF-16 编码的高位部分。
0xD800 ==》 1101 0100 0000 0000
高位:00001 11101 =补足16位=》 0000 0000 0011 1101
最终(二进制):1101 0100 0011 1101
最终(十六制): D 8 3 D
4. 将低位部分加上 0xDC00 得到第二个 16 位的编码单元,即 UTF-16 编码的低位部分。
0xDC00 ==》 1101 1100 0000 0000
低位:10000 00000 =补足16位=》 0000 0010 0000 0000
最终(二进制):1101 1110 0000 0000
最终(十六制): D E 0 0
5. 将这两个编码单元按照顺序排列,即先排列高位部分,再排列低位部分,得到最终的 UTF-16 编码。
\uD83D\uDE00
//1个unicode编码实际值不大于4位16进制数 == 转化成1个UTF16编码【16位的二进制,不够则左侧补0】
//总之每个UTF16必须是4位16进制数
代码
/**
* unicode转化
*@Author dong
*@Date 2023/4/13 上午 11:42
*@param unicodeStr
*@return
*/
private static String convert(String unicodeStr) {
if (unicodeStr.isEmpty()) {
return unicodeStr;
}
String[] parts = unicodeStr.split("-");
StringBuilder buff = new StringBuilder();
for (String s : parts) {
int part = Integer.parseInt(s, 16);
if (part >= 0x10000 && part <= 0x10FFFF) {
int hi = (int) (Math.floor((part - 0x10000) / 0x400) + 0xD800);
int lo = ((part - 0x10000) % 0x400) + 0xDC00;
Console.log("{} == 高位:{}【{}】、低位:{}【{}】", unicodeStr, hi, Integer.toHexString(hi),lo, Integer.toHexString(lo));
buff.append(new String(Character.toChars(hi)) + new String(Character.toChars(lo)));
} else {
buff.append(new String(Character.toChars(part)));
}
}
return buff.toString();
}
public static void main(String[] args) {
Console.log("\n=================================\n");
String convert = convert("1F600");
Console.log(convert);
Console.log("\uD83D\uDE00");
Console.log("\uD83C\uDC04");
// Integer.
}