Unicode 及其编码

Unicode是一种旨在统一全球文字编码的字符编码,解决多语言显示乱码问题。它包括ASCII的扩展,并通过UTF-8、UTF-16和UTF-32等多种编码方式在计算机中表示。UTF-8对不同Unicode范围使用不同字节数编码,UTF-16涉及字节序问题,而UTF-32直接用4字节编码每个字符。

Unicode 是在计算机中使用的一种字符编码,其出现是为了统一编码世界上所有的文字,符号。使之能在同一台计算机上正常显示,而不出现乱码。

早期计算机使用的是ASCII 编码,仅仅使用一个字节中的7 bit 来编码,其中编码了英文中使用的字母,数字,标点符号和一些不可见字符,如空格、回收等。后来扩展的ASCII 使用了一个字节的所有8 bit , 兼容之前的ASCII 编码,并提供一些控制字符。

但世界上语言上千种,每种语言有其自己的文字,符号。中文、法文、韩文、日文等。8 bit 只能编码256 个码位,不可能将这些文字都编进去。于是各国纷纷定义了本国文字的计算机编码。如中国使用的GBK 和GB2312,其使用2 byte 编码一个字符,这样能容纳下65536个码位,并且可以兼容之前的256 个 ASCII 扩展。但是问题来了,当这些编码在本国计算机中使用时,可以很好地工作,但当在一台计算机上要同时显示中文、法文时,出现了乱码。如 在中国的一台计算机,打开一个包含有法文和日文的文档时,使用的是GBK 编码,但GBK 编码定义了汉子,并没有编码法文和日文,将法文和日文的数据用GBK 解码,只能得到乱码。

于是有人希望将这些杂乱的编码方式使用一种同意的编码,将所有的文字符号都编码进去。历史上存在两个独立的尝试创立单一字符集的组织,一个是ISO, 一个是多语言软件制造商组成的统一码联盟。最后这两个组织合作,编制了统一的字码 。目前Unicode 使用的是ISO 10646-1的UCS字符集,其码位从0 —— 10FFFFh ,超出部分将不予赋值。

ISO 编制的UCS 编码有UCS-2 / 4 等计算机编码方式。

UCS-4 中每一个字符由4bytes 构成,最高位字节的最高bit 为0

group 为 0 的是BMP (Basic Multilingual Plane),每个Plane 有65536 个码位(row , cell) , Unicode 计划使用了17 个plane,共 17 * 65546 = 1114112 个码位,但在Unicode 5.0 版本中只使用了其中的238605 个码位,其他码位没有定义。

专用区: plane 15 和plane 16 上只定义了两个各占65534 个码位的专用区。

平面0 专用区: 0x E000 ~ 0x F8FF, 共6400 个,  0x D800 ~ 0x DFFF 共2048 个代理区。

最后计算下来,有 99089 个码位定义了字符 (238605 - 65534 * 2 - 6400 - 2048) ,其中定义了71226 个汉字。


Unicode 只是定义了符号文字的码位,并没有说明其在计算机中的表现形式。换句话说,知道中文 “中国” 的Unicode 为\u4e2d\u56fd,但其在计算机中到底使用多少字节编码,没有定义。目前Unicode 在计算机中的编码方式有UTF-8 / 16 / 32等。以下对常见的这三种作说明:

1、 UTF-8 编码:以字节为单位对Unicode 编码,当Unicode 在不同的范围内时,则使用的字节数不同。 其中x 代表编码的bit 位, 此编码方式不涉及到字节序问题。

Unicode                                                              UTF-8 (binary)

000000 - 00007F h                                           0xxxxxxx                               共126 (2^7)个码位,兼容ASCII

000080 - 0007FF h                                           110xxxxx  10xxxxxx             共2048 (2^12)个码位

000800 - 00FFFF h                                           1110xxxx   10xxxxxx 10xxxxxx           共65536 (2^16)个码位

010000 - 10FFFF h                                           11110xxx   10xxxxxx 10xxxxxx  10xxxxxx          共 2097152 (2 ^21) 个码位

如: “中国” 的Unicode 为\u4e2d \u56fd , 都在000800 - 00FFFF h 这一范围,则使用3byte 编码:

中: 0x4e2d = 0100,1110,0010,1101 b  ,顺次填充三个字节对应的格式模板 (红色部分), 1110,0100,1011,1000,1010,1101 b = 0x E4B8AD。

国: 0x56fd  =  0101,0110,1111,1101 b  ,UTF-8  = 1110,0101,1001,1011,1011,1101 b = 0x E59BBD。

(若不足位数则用0补高位)



2、 UTF-16 编码:以字为单位对Unicode 编码,注意,此编码方式会涉及到字节序问题。

1) 若 Unicode < 0x10000 , 则 UTF-16 编码就是 Unicode  的16进制数值,即编码使用一个字。

2) 若 Unicode >= 0x10000, 则UTF-16 编码为 x = Unicode - 0x 10000, 将 x 的二进制位填充到 110110xxxxxxxxxx 110111 xxxxxxxxxx b 的数据位部分,蓝色的两部分填充数据位,分别占10 bit ,共可编码 20 bit 的码位,此时使用两个字编码一个字符。


3、 UTF-32 编码:Unicode 的十六进制数即是其编码,这种编码涉及字节序问题。每一个字符都使用4 bytes 编码。


注: 在传输中,Unicode 建议使用 BOM (byte Order Mark,字节序标识)  来指定其字节序。即在传输数据的最前面先传输一个被用作BOM 的字符:

UTF 编码                          BOM

UTF-8 without BOM         无

UTF-8 with BOM               EFBBBF h

UTF-16 LE                         FFFE h

UTF-16 BE                         FEFF h

UTF-32 LE                         FFFE0000 h

UTF-32 BE                        0000FEFF h



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值