</p> UTF-8的特点是对分歧规模的字符使用分歧长度的编码。对于0×00-0×7F之间的字符,UTF-8编码与ASCII编码完全不异。UTF -8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0×10FFFF也只有 21位。 \8 j( R" J1 q' }; e- c2 c
例1:“汉”字的Unicode编码是0×6C49。0×6C49在 0×0800-0xFFFF之间,使用用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将0×6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次庖代模板中的x,获得:11100110 10110001 10001001,即E6 B1 89。0 W% _8 S1 Q1 R7 V" \* X
例2:Unicode编码0×20C30在0×010000-0×10FFFF之间,使用用4 字节模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。将0×20C30写成21位二进制数字(不足21位就在前面补0):0 0010 0000 1100 0011 0000,用这个比特流依次庖代模板中的x,获得:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。
8 @5 [6 W1 ]% n8 ?3 ] 106 C6 e! t( g- e0 P; l8 A) V+ A/ ]1 p
UTF-16) v4 e% Z& c+ |1 h3 G7 D
UTF-16编码以16位无符号整数为单元。我们把Unicode编码记作U。编码轨则如下:9 B w# c1 l- U; T$ z4 }
如不美观U《0×10000,U的UTF-16编码就是U对应的16位无符号整数(为书写精练,下文将16位无符号整数记作WORD)。( }& [$ @" e( k+ k6 l( t' ^
如不美观U≥0×10000,我们先计较U’=U-0×10000,然后将U’写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。# e! G2 J% ~1 i# {% W
为什么U’可以被写成20个二进制位?Unicode的最大码位是0×10ffff,减去 0×10000后,U’的最大值是0xfffff,所以必定可以用20个二进制位暗示。例如:Unicode编码0×20C30,减去0×10000后,获得0×10C30,写成二进制是:0001 0000 1100 0011 0000。用前10位依次替代模板中的y,用后10位依次替代模板中的x,就获得:1101100001000011 1101110000110000,即0xD843 0xDC30。& ]& d5 C! U$ y$ g
按照上述轨则,Unicode编码0×10000-0×10FFFF的UTF-16编码有两个WORD,第一个WORD的高6位是 110110,第二个 WORD的高6位是110111。可见,第一个WORD的取值规模(二进制)是11011000 00000000到11011011 11111111,即0xD800-0xDBFF。第二个WORD的取值规模(二进制)是11011100 00000000到11011111 11111111,即0xDC00-0xDFFF。
4 c- `9 `+ i B) L 为了将一个WORD的UTF-16编码与两个WORD的UTF-16编码区分隔来,Unicode编码的设计者将0xD800-0xDFFF保留下来,并称为代办代庖区(Surrogate):
3 Y$ X$ {1 \) v* Y" p; K2 G+ Q D800-DB7F ║ High Surrogates ║ 高位替代 z5 S9 |9 y' X ?, ]! G
DB80-DBFF ║ High Private Use Surrogates ║ 高位专用替代- Q; X% ~$ s" Z( l, f- U, j
DC00-DFFF ║ Low Surrogates ║ 低位替代
; _8 B( N/ E9 H5 h 高位替代就是指这个规模的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个规模的码位是两个WORD的UTF-16 编码的第二个WORD。那么,高位专用替代是什么意思?我们来解答这个问题,顺便看看怎么由UTF-16 编码推导Unicode编码。. p0 C' C5 c y; F7 ~6 C
如不美观一个字符的UTF-16编码的第一个WORD在0xDB80到0xDBFF之间,那么它的 Unicode编码在什么规模内?我们知道第二个WORD的取值规模是0xDC00-0xDFFF,所以这个字符的UTF-16编码规模应该是 0xDB80 0xDC00到0xDBFF 0xDFFF。我们将这个规模写成二进制:
^/ b7 }- Z8 t, B. O6 ^' c 1101101110000000 1101110000000000 – 1101101111111111 11011111111111118 \! S9 H4 B3 E0 m; G( P$ n, i
按照编码的相反轨范,掏出凹凸WORD的后10位,并拼在一路,获得! M& T+ t& \: O5 v! R4 k8 H
1110 0000 0000 0000 0000 – 1111 1111 1111 1111 1111# h% U* D) V5 j+ r6 p7 R, \
即0xe0000-0xfffff,按照编码的相反轨范再加上0×10000,获得0xf0000-0×10ffff。这就是UTF-16编码的第一个 WORD在0xdb80到0xdbff之间的Unicode编码规模,即平面15和平面16。因为Unicode尺度将平面15和平面16都作为专用区,所以0xDB80到0xDBFF之间的保留码位被称作高位专用替代。3 Z# K [, {* z$ w
UTF-32
6 W/ r6 G D" C; _2 l# {! l UTF-32编码以32位无符号整数为单元。Unicode的UTF-32编码就是其对应的32位无符号整数。 |