不晓得说啥子
全部博文(42)
分类: C/C++
2015-04-11 20:17:53
UTF-16简介:
UTF-16是用16bit编码来表达Unicode,这样表达范围是216(即65536),也就是UTF-16的代码单元(Code Unit)为16bits。如果表达BMP内的字符,用一个UTF-16的Code Unit就可表达,对于辅助平面内的字符,UTF-16有巧妙的设计。落在BMP内,从U+D800到U+DFFF之间的Code Point区段是永久保留不映射到字符, UTF-16利用这保留下来的0xD800-0xDFFF区段的CodePoint来对辅助平面内的字符的Code Point进行编码。所以可以将unicode对应的字符编码表分解为两部分: U+0000...U+D7FF (U+D800....U+DFFF(保留,用作四个字节编码的代理)) U+E000.. U+FFFF | U+10000.. U+10FFFF
对U+0000.. U+D7FF以及U+E000.. U+FFFF的编码(不包含U+D800到U+DFFF)
UTF-16与UCS-2对这个范围内的CodePoint进行编码,采用单个16bit长的CodeUnit,数值等价于对应的Code Point。BMP中的这些Code Point是仅有的可以被UCS-2表示的Code Point。
对U+10000.. U+10FFFF的编码
辅助平面(Supplementary Planes)中的CodePoint,在UTF-16中被编码为一对16bit长的Code Unit(即32bit,4Bytes),称作代理对(surrogate pair)。
具体方法是:
UTF-16解码 |
||||
hi \ lo |
DC00 |
DC01 |
… |
DFFF |
D800 |
10000 |
10001 |
… |
103FF |
D801 |
10400 |
10401 |
… |
107FF |
? |
? |
? |
? |
? |
DBFF |
10FC00 |
10FC01 |
… |
10FFFF |
这样,这个范围内的字符就被编码成了一个代理对[lead surrogate,trail surrogate]:两个16bits的Code Unit,取值范围分别是0xD800..0xDBFF和0xDC00..0xDFFF。而BMP中得到的Code Unit的范围是0x0000..0xFFFF(0xD800..0xDFFF是保留的,不包含其中),所以这三个区段是相互不重叠的,在解码时很容易实现。
下面以对U+64321的UTF-16编码为例,看一下对于辅助平面内的字符是如何编码的:
V = 0x64321
Vx = V - 0x10000
= 0x54321
= 01010100 0011 0010 0001
Vh = 01 0101 0000 // Vx 的高位部份的 10 bits
Vl = 11 0010 0001 // Vx 的低位部份的 10 bits
w1 = 0xD800 // 结果的前16位元初始值
w2 = 0xDC00 // 结果的后16位元初始值
w1 = w1 | Vh
= 1101 1000 0000 0000
| 01 0101 0000
= 1101 1001 0101 0000
= 0xD950
w2 = w2 | Vl
= 1101 1100 0000 0000
| 11 0010 0001
= 1101 1111 0010 0001
= 0xDF21
所以,这个字 U+64321 最终的 UTF-16 编码是:
0xD950 0xDF21