Unicode UTF-8 UTF-16 UTF-32的关系

Unicode (统一码 万国码)产生的背景

预备知识:编码

  1. 计算机只认识二进制数字 好比:010101 单位bit
  2. 通常来讲,计算机的最小存储单元是 8位二进制数 也就是1字节
  3. 想要让计算机认识字符 例如英文字符 a ,须要对字符进行 编码
  4. 咱们常说的 ASCII(American Standard Code for Information Interchange)编码是使用一个字节的存储长度对字符的编码集。

为什么要有Unicode?

ASCII编码使用 8bit (b0-b7)中的最高位b7位做为 奇偶校验位,用来保障传输的可靠性,因此ASCII一共定义了2^7=128个字符集合。代理

所谓奇偶校验,是指在代码传送过程当中用来检验是否出现错误的一种方法,通常分奇校验和偶校验两种。 奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添0; 偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1) code

ASCII编码的问题

ASCII编码是美国制定的编码标准,它能够表明英文中的字符集合,但用来表示其余语言 如汉语、法语等是不够用的。 中国为了让计算机识别汉语,制定了GB2312编码规范,使用两个字节表明一个汉字,支持65536个汉字。orm

这样发展的趋势是 每一个国家或地区制定本身语言的计算机字符编码,致使混乱不堪。unicode

Unicode产生

Unicode 正是解决这个问题而诞生的,它对世界上绝大部分的文字的进行整理和统一编码。开发

事实上,历史上存在两个独立的尝试创立单一字符集的组织,即国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟。前者开发的 ISO/IEC 10646 项目,后者开发的统一码项目。所以最初制定了不一样的标准。it

1991年先后,两个项目的参与者都认识到,世界不须要两个不兼容的字符集。因而,它们开始合并双方的工做成果,并为创立一个单一编码表而协同工做。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得二者保持一致。io

两个项目仍都存在,并独立地公布各自的标准。但统一码联盟和ISO/IEC JTC1/SC2都赞成保持二者标准的码表兼容,并紧密地共同调整任何将来的扩展。字符编码

在发布的时候,Unicode通常都会采用有关字码最多见的字型,但ISO 10646通常都尽量采用Century字型。(摘自百度百科https://baike.baidu.com/item/Unicode)table

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编码的计算机实现是有多种的。 不一样的实现方式实际上是对Unicode的存储方式存在着差别,计算机实现Unicode能够认为是对Unicode的存储编码。

在这里咱们已经进行了两次编码转换了,Unicode自己是字符对应数字的编码方案,而Unicode的计算机实现是Unicode对应的计算机存储编码方案。

为何对计算机实现还要对Unicode作一次编码???

下面咱们经过介绍不一样的Unicode计算机实现方案来讨论一下这个问题。

咱们应当知道,生活中的字符出现的几率是不同的。例如,生活中咱们经常使用 “你好” “早”等词汇,可是“耄耋” “饕餮”等这些字符咱们不多用到。

基于以上的事实,若是咱们把 “你好” “早”等这些高几率出现的字符 使用较短的存储编码,而那些不多用到的字符使用较长的存储编码,

定义: 假设有n个字符c1.....cn,每一个字符出现的几率为p(n),每一个字符的存储空间为s1.....sn,那么, 字符平均存储空间计算公式: T = p(1)*s1+......p(n)*sn

下面咱们分别计算一下不一样编码实现方案的字符平均存储空间。

UTF-32

最容易想到的,也是最简单的计算机实现就是用四个字节(32bit)对Unicode编码字符进行存储,这就是UTF-32。UTF-32是最简单的程序实现方案(无需转换,与Unicode编码一一对应)。

好处:无需转换,速度快

坏处:浪费存储空间

T = 32bit

UTF-8

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)

这样编码感受复杂度变高了不少啊,可是, 好处在于节省了存储空间,另外,兼容了旧的ASCII编码。

T=???

暂时没有字符几率数据,等我查资料再更新。

UTF-16

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 ) 要做为保留字符了

UTF-16既保留了解析速度,同时也比较节省存储空间。这个是UTF-8和UTF-32二者优势的结合。

T=??? 暂时没有字符几率数据,等我查资料再更新。

相关文章
相关标签/搜索