a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 122|回复: 1

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

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证之Java中编码以及Unicode总结(7)! y* r& C4 z( j  {1 p, s8 x3 P
4.2 UCS编码8 t. f# ?$ [+ M' _% M
  早期的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。
$ C4 g" g% r4 c  ]3 t  每个平面有2^16=65536个码位。
* u7 M1 s$ T7 ]8 Z3 \1 R# Z  4.3 UTF编码
4 C+ E! p$ n7 Q$ W3 J  Unicode 尺度的编码字符集的字符编码方案。UTF是 Unicode Translation Format,即把Unicode转做某种名目的意思。UTF-32、UTF-16 和 UTF-8 是Unicode 尺度的编码字符集的字符编码方案,UTF-16 使用一个或两个未分配的
- x. p2 x7 X3 K( V: |5 l7 |+ C' G3 w  9
( Y$ ^4 i' [0 B! H9 M+ n  }2 k8 M  16位代码单元的序列对Unicode 代码点进行编码;UTF-32 即将每一个 Unicode 代码点暗示为不异值的 32 位整数。
% n+ `0 w- |; n, @4 g$ m0 w. N  在Unicode中:汉字“字”对应的数字是23383。在Unicode中,我们有良多体例将数字23383暗示成轨范中的数据,搜罗: UTF-8、 UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换名目,即若何将Unicode界说的数字转换成轨范数据。例如,“汉字”对应的数字是 0×6c49和0×5b57,而编码的轨范数据是:
! k4 x9 h/ w) O" V% k3 F7 H+ a  BYTE data_utf8[] = {0xE6, 0xB1, 0×89, 0xE5, 0xAD, 0×97}; // UTF-8编码
) k* N- n6 z) S1 K5 V! S+ u  WORD data_utf16[] = {0×6c49, 0×5b57}; // UTF-16编码
' u5 z+ o& o: i* S! x  DWORD data_utf32[] = {0×6c49, 0×5b57}; // UTF-32编码
8 v8 u- o5 L$ T; A8 G7 F" Q  这里用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。
% A5 `% K1 a9 }  [: R2 }  UTF-8
+ v$ j# E: R9 l  UTF-8最多是使用3个字节来暗示一个字符。但理论上来说,UTF-8最多需要用6字节暗示一个字符。
" j3 u# b, m: S, W  00000000-0000007F的字符,用单个字节来暗示;
" ]. r$ K3 G% ~2 S( t. L; o  00000080-000007FF的字符用两个字节暗示(中文的编码规模): g. q" f$ Z8 S5 {: d- g
  00000800-0000FFFF的字符用3字节暗示
& `8 @1 r: \" e9 Z) O% w7 l* a  UTF-8以字节为单元对Unicode进行编码。从Unicode到UTF-8的编码体例如下:9 C: @0 P( Y9 m
  Unicode编码 ║ UTF-8 字节约(二进制): e1 v$ \2 p7 K: v
  000000 – 00007F ║ 0xxxxxxx 7bit
5 w9 h6 E/ V4 H9 N  000080 – 0007FF ║ 110xxxxx 10xxxxxx 11bit8 Y! m9 A# `& x
  000800 – 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx 16bit
6 Z: x: X: z6 o2 u* k& R. _( ?$ Y9 J! P# ~. y+ h! p2 P: h
  010000 – 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 21bit
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:45 | 显示全部楼层

Java认证:Java中编码以及Unicode总结(7)

</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位无符号整数。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 16:55 , Processed in 0.226428 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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