a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 143|回复: 0

[专业语言] Java认证之Java中编码以及Unicode总结(7)

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之Java中编码以及Unicode总结(7)
; H( A1 J3 y0 X3 y8 v, K% q/ T# X4.2 UCS编码
! k2 t; r3 M8 }; v, x; x  早期的Unicode标准有UCS-2、UCS-4的说法。UCS-2用两个字节编码,UCS-4用4个字节编码。UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个平面(plane)。每个平面根据第3个字节分为256行(row),每行有 256个码位(cell)。group 0的平面0被称作BMP(Basic Multilingual Plane)。将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。
  D9 j3 m) v2 F0 G; W1 Q  每个平面有2^16=65536个码位。- b3 \! g6 k' R- J+ J: J) s
  4.3 UTF编码
, }2 ^1 p2 N1 w6 F4 C5 Y3 k& y  Unicode 标准的编码字符集的字符编码方案。UTF是 Unicode Translation Format,即把Unicode转做某种格式的意思。UTF-32、UTF-16 和 UTF-8 是Unicode 标准的编码字符集的字符编码方案,UTF-16 使用一个或两个未分配的0 v( B" ?9 m" g) n9 Q3 b# k
  92 c; S+ u. x! p- n$ z3 y- x' I6 \
  16位代码单元的序列对Unicode 代码点进行编码;UTF-32 即将每一个 Unicode 代码点表示为相同值的 32 位整数。5 y4 E; d$ K6 X" t! N
  在Unicode中:汉字“字”对应的数字是23383。在Unicode中,我们有很多方式将数字23383表示成程序中的数据,包括: UTF-8、 UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。例如,“汉字”对应的数字是 0×6c49和0×5b57,而编码的程序数据是:) E1 [1 U( [- O: ^: t
  BYTE data_utf8[] = {0xE6, 0xB1, 0×89, 0xE5, 0xAD, 0×97}; // UTF-8编码0 @" [4 y2 O& R% }- C! V+ ?9 Z
  WORD data_utf16[] = {0×6c49, 0×5b57}; // UTF-16编码6 j/ {, q% @: `9 H* T# M
  DWORD data_utf32[] = {0×6c49, 0×5b57}; // UTF-32编码
/ k5 N" \/ Q8 V, A# E4 Y  这里用BYTE、WORD、DWORD分别表示无符号8位整数,无符号16位整数和无符号32 位整数。UTF-8、UTF-16、UTF-32分别以BYTE、WORD、DWORD作为编码单位。“汉字”的UTF-8编码需要6个字节。“汉字”的 UTF-16编码需要两个WORD,大小是4个字节。“汉字”的UTF-32编码需要两个DWORD,大小是8个字节。根据字节序的不同,UTF-16可以被实现为UTF-16LE或UTF-16BE,UTF-32可以被实现为UTF-32LE或UTF-32BE。下面介绍UTF-8、UTF-16、 UTF-32、字节序和BOM。# Q4 N2 a! e. C3 Z) I
  UTF-8* N4 F% `) g) Z& s7 h4 I1 E
  UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。( |5 W5 b& C% m. m1 a% X
  00000000-0000007F的字符,用单个字节来表示;0 B9 W+ J* D8 @+ [# B2 h9 C$ |
  00000080-000007FF的字符用两个字节表示(中文的编码范围)' [5 q6 i- ?$ j
  00000800-0000FFFF的字符用3字节表示
# y! b; X2 k1 G/ Z- J( k  UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:% @8 ^1 b, n" c' x; j, Z0 U
  Unicode编码 ║ UTF-8 字节流(二进制), o1 }* f( m" s4 X& g: p8 Z
  000000 – 00007F ║ 0xxxxxxx 7bit
) J. n7 ?5 O* l; u0 [6 t' h  000080 – 0007FF ║ 110xxxxx 10xxxxxx 11bit4 c7 l' h9 m6 o
  000800 – 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx 16bit6 C4 P. B0 Y6 G8 O4 f
  010000 – 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 21bit
/ ~" c5 O& {/ e+ \. {1 _. h  UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0×00-0×7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF -8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0×10FFFF也只有 21位。
2 Y4 m2 y. ]3 I  例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。
' [2 M$ ~: i. b4 `8 g( W( W2 I  例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。' b6 \, C. R1 z7 M" C0 [
  10
0 T& ^. ]$ B6 T! x. r* Y  UTF-16
) c7 j, e* Z/ e( P  j. j1 W* ]( I0 U  UTF-16编码以16位无符号整数为单位。我们把Unicode编码记作U。编码规则如下:0 c- O5 X! }+ a# H
  如果U《0×10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记作WORD)。0 |2 \  m1 `) |  ]
  如果U≥0×10000,我们先计算U’=U-0×10000,然后将U’写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。: R' B& p" g& P. l1 b& z& y4 F
  为什么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。3 o$ X+ V$ C! U
  按照上述规则,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。
/ i( n  r/ `+ s4 L. ]$ O$ c  为了将一个WORD的UTF-16编码与两个WORD的UTF-16编码区分开来,Unicode编码的设计者将0xD800-0xDFFF保留下来,并称为代理区(Surrogate):+ J3 Y9 Y+ A' @; ?; F! Q7 E% A  Z
  D800-DB7F ║ High Surrogates ║ 高位替代" `& ^1 s) L2 H$ U  c( S
  DB80-DBFF ║ High Private Use Surrogates ║ 高位专用替代
) o/ \( E$ _, ^8 Z* @  DC00-DFFF ║ Low Surrogates ║ 低位替代
& X- k+ m$ [4 Z7 y  高位替代就是指这个范围的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个范围的码位是两个WORD的UTF-16 编码的第二个WORD。那么,高位专用替代是什么意思?我们来解答这个问题,顺便看看怎么由UTF-16 编码推导Unicode编码。$ {9 X5 R  q$ z  b0 \0 e9 V
  如果一个字符的UTF-16编码的第一个WORD在0xDB80到0xDBFF之间,那么它的 Unicode编码在什么范围内?我们知道第二个WORD的取值范围是0xDC00-0xDFFF,所以这个字符的UTF-16编码范围应该是 0xDB80 0xDC00到0xDBFF 0xDFFF。我们将这个范围写成二进制:
5 U1 W5 ]7 y+ S! G" O7 G2 Z  1101101110000000 1101110000000000 – 1101101111111111 1101111111111111
1 c7 O* }! U1 E" I2 I' B  按照编码的相反步骤,取出高低WORD的后10位,并拼在一起,得到7 M5 @1 c8 X7 }+ q
  1110 0000 0000 0000 0000 – 1111 1111 1111 1111 1111) G1 e4 C  b# v( c- c
  即0xe0000-0xfffff,按照编码的相反步骤再加上0×10000,得到0xf0000-0×10ffff。这就是UTF-16编码的第一个 WORD在0xdb80到0xdbff之间的Unicode编码范围,即平面15和平面16。因为Unicode标准将平面15和平面16都作为专用区,所以0xDB80到0xDBFF之间的保留码位被称作高位专用替代。
( A1 D8 d+ U1 G' d0 V2 N8 \. i: @UTF-323 m6 h0 L' Q. Z8 I
  UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-3 01:13 , Processed in 0.490133 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表