背景
升级项目的Unity版本到2020,之前扩展的文本组件超链接功能不能用了,因为TextGenerator改版了,以前空白字符和富文本标签是有顶点数据的,现在没有了,导致字符和顶点信息对应不上了。解决的期间发现有的字符会被拆成两个char,感到不解,于是有了下文的总结。
总结
字符集规定字符和数字的映射关系。
字符编码规定字符如何编码、存储。
Unicode是字符集,UTF-8是字符编码。
UTF:Unicode Transformation Format,Unicode转换格式。
代码点(code point,码位):Unicode规定的,用来映射字符的数字。但一个字符可能由多个代码点组成。比如 é 是由两个代码点 \u0065\u0301 组成的。
代码单元(code unit,码元):一个编码模型中,用来代表字符的最小的字节单位。比如UTF-8,代码单元就是1个字节(8个比特位)。
BOM(Byte Order Mark) 字节序标记:字符“Zero Width No-Break Space”,零宽度非换行空格,FEFF。如果是FE FF,则为大端;如果是反过来FF FE,则为小端。
大端(Big endian)和小端(Little endian):按字节,不是按位。从左到右,从高位到低位,则为大端,内存低地址处放高位。反之为小端。大端的好处是可以提前判断报文信息,小端适用于加法运算,因为有进位。
下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:
short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址单元
x1=((char*)&x)[1]; //高地址单元
UTF-8:变长编码,1-6个字节表示。具体规则网上很多,大致是零平面用0开头,其他平面第一个字节用前面连续的几个1表示总共需要几个字节表示这个字符,然后用一个0隔开,后面几个字节用10开头,剩余位依次填充码点比特位:
UTF-16:把Unicode字符集的抽象码映射为16个比特位的整数,C# 中的 char 就是16位的。第零平面用8位即可满足(65536个)。其他平面,即辅助平面,用两个16比特的整数的代理对实现。
代理对(surrogate pair):UTF-16中,16个比特位不足以映射所有的Unicode字符。所以,第零平面保持原本的映射,用16位表示。辅助平面需要20位来表示,则用两个16位整数表示。具体方法是:
- 代码点减去第零平面0x10000,得到0->0xFFFFF,总共需要20位。
- 高位的10位加上0xD800,得到高位代理。
- 低位的10位加上0xDC00,得到低位代理。
Unicode详解
对于字符编码,程序员的话应该了解它的哪些方面?
字符编码笔记:ASCII,Unicode 和 UTF-8
Unicode标准以及其常见的编码方案