如何将Unicode码点转换成UTF-8和UTF-16编码?
摘要:熟悉Unicode标准的朋友都知道,统一码的码点(又称码值),在使用往往不是直接使用,而是使用UTF-8或UTF-16或UTF-32编码方法来进行编码后再用。 UTF32编码就是直接用四字节来表示Unicode编码,不足四字节的补0,这样对
熟悉Unicode标准的朋友都知道,统一码的码点(又称码值),在使用往往不是直接使用,而是使用UTF-8或UTF-16或UTF-32编码方法来进行编码后再用。 UTF32编码就是直接用四字节来表示Unicode编码,不足四字节的补0,这样对英文等字符集很小的文字来讲,一个英文字母,在ASCII字符集里只要1个字节就能表达,在UTF32下要四个字节,甚是浪费,因此使用并不多。主要我们能碰到的大都是UTF-8,少部分是UTF-16编码后的Unicode字符。
UTF-16是比较早出现的编码方式,早期用2个字节来表达Unicode编码,它只适用于目前Unicode平面的中的基本平面,也就是很早期Unicode收字比较少的时候。后来标准收集的字符多了,必须得扩容,才发展出用代理对来表达BMP之外的更多的字符。因此,对于BMP部分的Unicode字符,UTF-16编码就是它自身的码点,不足2字节的高位加0来补齐,适用于0xFFFF以下的字符。对于BMP部分之外的5位hex值的字符码点(目前标准还没有6位hex的码值),以四个字节来表达,高位2字节用D800~DBFF,低位两字节用DC00~DFFF组合来表达。为了表达成这样,数字需要经过一定的转换,转换的规则有兴趣的可以网上搜索一下,这里不赘述,在下面的代码中体现。
UTF8根据字符码点大小的不同,分成不同字节数来表示。在0x7F以下的用一个字节,也就是它自身的编码来表示。 0x80~0x7FF之间的用两个字节来表示,0x800~0xFFFF之间 的用三个字节来表示,大部分常用汉字处于0x4e00~0x9FFF之间,因此大部分常用汉字的UTF8编码,都是三个字节长度; 更大一点,0x10000~0x1FFFFF这个区间的字符,其UTF8编码就需要用四个字节来表示,比如𰻝𰻝面的𰻝字,罕用的姓氏““。
UTF-8 或UTF-16编码后的字符,在存放到文件中时,还有一个大端序和小端序的问题,其实就是字节在内存空间排列的顺序选择。比如UTF-8编码后的“丁“字是E4B881,这是一个3字节的十六进制数。E4这一侧称为数字的高位,81称为这一数字的低位。这个数字存放在内存(或文件中)如果按地址从小到大,依次是 E4 B8 81,这种排列与人们阅读时从高到低的习惯相符,称为大端序(big Endian,缩写BE)。 如果存放时低位在低地址,高位在高地址,依次是81 B8 E4,这种排列顺序就是小端序(Little Endian,缩写LE)。BE与LE的排列顺序正好是相反的。
大端序常用于网络通信(网络字节序)和某些文件格式,因为它更符合人类的阅读习惯。但现代处理器中更多的是小端序,如x86、ARM等芯片,因为它在处理器设计中效率更高。
为了练习一下位的操作并巩固下Unicode编码之UTF-8,UTF-16的计算方式,写了个简易的小程序,注意这里面用的都是Unicode码点(16进制数字)而非字符本身。
