a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 139|回复: 0

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

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之Java中编码以及Unicode总结(7)
2 O& A# |" \  Y% ^4.2 UCS编码
, s2 [+ W: h% {  S8 @: a! 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。$ C9 s' K) k; |  `6 H0 S
  每个平面有2^16=65536个码位。
3 q8 ^# w) h% K+ m" X8 H( t  4.3 UTF编码
) C/ Q$ ^9 P% S1 C" ^6 j6 {  Unicode 标准的编码字符集的字符编码方案。UTF是 Unicode Translation Format,即把Unicode转做某种格式的意思。UTF-32、UTF-16 和 UTF-8 是Unicode 标准的编码字符集的字符编码方案,UTF-16 使用一个或两个未分配的5 F3 ]4 Y3 S- c: i
  9$ X- T* d  j* o0 U; [4 b) y$ {
  16位代码单元的序列对Unicode 代码点进行编码;UTF-32 即将每一个 Unicode 代码点表示为相同值的 32 位整数。7 h& x$ g& p0 q9 X* e
  在Unicode中:汉字“字”对应的数字是23383。在Unicode中,我们有很多方式将数字23383表示成程序中的数据,包括: UTF-8、 UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。例如,“汉字”对应的数字是 0×6c49和0×5b57,而编码的程序数据是:! R( d# P- s. [5 L9 m
  BYTE data_utf8[] = {0xE6, 0xB1, 0×89, 0xE5, 0xAD, 0×97}; // UTF-8编码. L, q5 p  N* }# X! _
  WORD data_utf16[] = {0×6c49, 0×5b57}; // UTF-16编码
$ }& ^7 _. H/ q4 D7 K2 g  DWORD data_utf32[] = {0×6c49, 0×5b57}; // UTF-32编码5 W6 L8 V/ L9 ?1 F
  这里用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。' e# ]" P' r5 x& D. C) \
  UTF-83 z5 t7 f  U4 a: W  m; H3 q
  UTF-8最多是使用3个字节来表示一个字符。但理论上来说,UTF-8最多需要用6字节表示一个字符。0 b4 h' L& `- s9 R
  00000000-0000007F的字符,用单个字节来表示;
6 S7 X  z' P7 ^2 z' K  00000080-000007FF的字符用两个字节表示(中文的编码范围)
/ n2 t% F) G# G& P" R  00000800-0000FFFF的字符用3字节表示
4 J: J8 O, Q/ L9 v+ ]2 s) ^  UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:1 |0 ]+ e; j- X* ]/ ]1 p. `% I
  Unicode编码 ║ UTF-8 字节流(二进制)9 y/ j( v* W; D2 J) J3 S. j0 V
  000000 – 00007F ║ 0xxxxxxx 7bit& I& A& d; I& {/ n4 @9 o
  000080 – 0007FF ║ 110xxxxx 10xxxxxx 11bit2 E& u- f4 [' r$ ?! `1 F6 O. |, p
  000800 – 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx 16bit
7 A/ i5 L7 @3 t- w& A* R# z  010000 – 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 21bit4 l1 k' j4 E% G1 j' H
  UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0×00-0×7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF -8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0×10FFFF也只有 21位。5 l, W% M1 \6 P7 {' 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。6 ?& Z8 P" A/ z7 @
  例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。% Z7 G! X9 Y4 X) O% [* e
  102 [# y0 r6 H4 V- ^- a( v
  UTF-16
3 j  ~! W; u* z" m, A% U& s) k  UTF-16编码以16位无符号整数为单位。我们把Unicode编码记作U。编码规则如下:3 w0 J$ g6 J% L
  如果U《0×10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记作WORD)。
) K9 i6 n! K( T  p  如果U≥0×10000,我们先计算U’=U-0×10000,然后将U’写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。7 p: K2 p9 u; J, P! l
  为什么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。: O& X( k+ Q1 r6 L/ ]& C2 A( Q: 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。' w# `& d$ M; D# l- B/ P
  为了将一个WORD的UTF-16编码与两个WORD的UTF-16编码区分开来,Unicode编码的设计者将0xD800-0xDFFF保留下来,并称为代理区(Surrogate):
' E6 s" J+ m$ B2 `0 n* Z  D800-DB7F ║ High Surrogates ║ 高位替代$ i7 _7 o" x: c( J5 j
  DB80-DBFF ║ High Private Use Surrogates ║ 高位专用替代
$ o: U( u3 m! J. {  DC00-DFFF ║ Low Surrogates ║ 低位替代
# ]# O' |9 ]! u6 G9 |9 ]  高位替代就是指这个范围的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个范围的码位是两个WORD的UTF-16 编码的第二个WORD。那么,高位专用替代是什么意思?我们来解答这个问题,顺便看看怎么由UTF-16 编码推导Unicode编码。
- b$ ~- Q( J9 q. s& x  如果一个字符的UTF-16编码的第一个WORD在0xDB80到0xDBFF之间,那么它的 Unicode编码在什么范围内?我们知道第二个WORD的取值范围是0xDC00-0xDFFF,所以这个字符的UTF-16编码范围应该是 0xDB80 0xDC00到0xDBFF 0xDFFF。我们将这个范围写成二进制:
' v  j" c# }/ f( R6 X, P/ ^  1101101110000000 1101110000000000 – 1101101111111111 1101111111111111
# u$ ~6 i4 G) W: n" d: D( D( i3 R  按照编码的相反步骤,取出高低WORD的后10位,并拼在一起,得到& f: {  _: t0 H, ~' Q# B7 @
  1110 0000 0000 0000 0000 – 1111 1111 1111 1111 1111
* n; Y  w3 t, Y& e8 \  即0xe0000-0xfffff,按照编码的相反步骤再加上0×10000,得到0xf0000-0×10ffff。这就是UTF-16编码的第一个 WORD在0xdb80到0xdbff之间的Unicode编码范围,即平面15和平面16。因为Unicode标准将平面15和平面16都作为专用区,所以0xDB80到0xDBFF之间的保留码位被称作高位专用替代。. a2 \: d0 o6 L: z- T6 c& Q
UTF-32
5 Z* i$ Q; Q* P5 A; `. K. D( W7 e  UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 02:47 , Processed in 0.175686 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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