Unicode 与 utf8 utf16 utf32的关系

Unicode是计算机领域的一项行业标准,它对世界上绝大部分的文字的进行整理和统一编码,Unicode的编码空间可以划分为17个平面(plane),每个平面包含2的16次方(65536)个码位。17个平面的码位可表示为从U+0000到U+10FFFF,共计1114112个码位,第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0)。其他平面称为辅助平面(Supplementary Planes)。基本多语言平面内,从U+D800到U+DFFF之间的码位区段是永久保留不映射到Unicode字符,所以有效码位为1112064个。

Unicode的编码方式

unicode 只是一种字符码表, 而在计算机中进行存储时, 必须指定一种具体的存储方式。常见的如utf8, utf16, utf32

比如,对于英文字符A , 在unicode中的值是65, 其在计算机中存储时, 使用utf8 utf16 utf32等不同格式存储时, 是完全不同的。

utf8存储,在内存中就是0x41;  utf16存储,在内存中就是0x0041 ; utf32存储,在内存中就是0x00000041

在windows编程中, 字符格式通常有多字节(ansic)与宽字符(unicode)之分。 很多时候,我们认为unicode就是用两个字符来表示英文字母, 其实这是不准确的。 因为windows中,默认的unicode编码方式就是utf16, 所以英文字符才是两个字节。

 

UTF-8(8-bit Unicode Transformation Format)

UTF-8是一种变长编码,对于一个Unicode的字符被编码成1至4个字节。Unicode编码与UTF-8的编码的对应关系:

Unicode编码UTF-8编码(二进制)
U+0000 – U+007F 0xxxxxxx
U+0080 – U+07FF 110xxxxx 10xxxxxx
U+0800 – U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

一个字节的uft8表示的unicode 码范围为(0 ~0x7F)

两个字节长度的uft8 表示的unicode码范围为(0x80 ~ 0x07FF)

三个字节长度的uft8 表示的unicode码范围为(0x0800 ~ 0xFFFF)

四个字节长度的uft8 表示的unicode码范围为( 0x10000 ~ 0x10FFFF)

 

其中绝大部分的中文用三个字节编码,部分中文用四个字节编码,举例如下:

Unicode字符UTF-8编码
U+0041 A 0x41
U+7834 0xE7 0xA0 0xB4
U+6653 0xE6 0x99 0x93
U+2A6A5 𪚥(四个龍) 0xF0 0xAA 0x9A 0xA5

UTF-16(16-bit Unicode Transformation Format)

UTF-16也是一种变长编码,对于一个Unicode字符被编码成1至2个码元,每个码元为16位。

基本多语言平面(码位范围U+0000-U+FFFF)

在基本多语言平面内的码位UTF-16编码使用1个码元且其值与Unicode是相等的(不需要转换)。举例如下

Unicode字符UTF-16(码元)UTF-16 LE(字节)UTF-16 BE(字节)
U+0041 A 0x0041 0x41 0x00 0x00 0x41
U+7834 0x7834 0x34 0x78 0x78 0x34
U+6653 0x6653 0x53 0x66 0x66 0x53

辅助平面(码位范围U+10000-U+10FFFF)

在辅助平面内的码位在UTF-16中被编码为一对16bit的码元(即32bit,4字节),称作代理对(surrogate pair)。组成代理对的两个码元前一个称为前导代理(lead surrogates)范围为0xD800-0xDBFF,后一个称为后尾代理(trail surrogates)范围为0xDC00-0xDFFF。

具体的转换过程为

1 首先将unicode码表 - 0x10000 , 这样得到的辅助平面的码表范围为(U+0000 - U+FFFFF) ,总共最多20bit

2  将20bit ,分为high 10bit 与 low 10bit。 high 1bit | 0xD800 得到前导代理, low 10bit | 0xDC00 得到后尾代理

从这里也可以理解为什么 在基本多语言平面中, (U+D800  ~ U+DFFF ) 要作为保留字符了

 

举例如下

 

Unicode字符UTF-16(码元)UTF-16 LE(字节)UTF-16 BE(字节)
U+2A6A5 𪚥 0xD869 0xDEA5 0x69 0xD8 0xA5 0xDE 0xD8 0x69 0xDE 0xA5

UTF-32(32-bit Unicode Transformation Format)

UTF-32是一种定长编码,使用1个32bit的码元,其值与Unicode编码值相等。举例如下:

 

Unicode字符UTF-32(码元)UTF-32 LE(字节)UTF-32 BE(字节)
U+0041 A 0x00000041 0x41 0x00 0x00 0x00 0x00 0x00 0x00 0x41
U+7834 0x00007834 0x34 0x78 0x00 0x00 0x00 0x00 0x78 0x34
U+6653 0x00006653 0x53 0x66 0x00 0x00 0x00 0x00 0x66 0x53
U+2A6A5 𪚥 0x0002A6A5 0xA5 0xA6 0x02 0x00 0x00 0x02 0xA6 0xA5

posted @ 2018-05-02 17:48  myd620  阅读(5234)  评论(0编辑  收藏  举报