Unicode,也被称为统一码、万国码或单一码,是计算机科学领域的一个业界标准,它包括字符集和编码方案等。Unicode的产生是为了解决一些问题。
首先,为什么需要Unicode?ASCII编码使用8位中的最高位作为奇偶校验位,用于传输的可靠性。因此,ASCII只定义了128个字符集合(2^7)。然而,ASCII编码仅能表示英文字符集,无法满足其他语言如汉语、法语等的需求。为了让计算机能够识别汉语,中国制定了GB2312编码规范,每个汉字用两个字节表示,支持了65536个汉字。
但是,由于每个国家或地区都制定了自己语言的计算机字符编码,导致了混乱和不兼容的情况。这种发展趋势并不可持续。因此,Unicode的引入解决了这些问题。它为全球范围内的字符集合提供了一个统一的编码方案,为不同的语言和文化提供了支持,使得国际化的计算机交流更加便捷和无障碍。
3.Unicode产生
Unicode 正是解决这个问题而诞生的,它对世界上绝大部分的文字的进行整理和统一编码。
事实上,历史上存在两个独立的尝试创立单一字符集的组织,即国际标准化组织(ISO)和多语言软件制造商组成的统一码联盟。前者开发的 ISO/IEC 10646 项目,后者开发的统一码项目。因此最初制定了不同的标准。
1991年前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。
两个项目仍都存在,并独立地公布各自的标准。但统一码联盟和ISO/IEC JTC1/SC2都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。
在发布的时候,Unicode一般都会采用有关字码最常见的字型,但ISO 10646一般都尽可能采用Century字型。
—来自百度百科
二、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
下面我们分别计算一下不同编码实现方案的字符平均存储空间。
1.UTF-32
最容易想到的,也是最简单的计算机实现就是用四个字节(32bit)对Unicode编码字符进行存储,这就是UTF-32。UTF-32是最简单的程序实现方案(无需转换,与Unicode编码一一对应)。
好处:无需转换,速度快
坏处:浪费存储空间
T = 32bit
2.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编码。
3.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。
具体的转换过程为:
-
首先将unicode码表 – 0x10000 , 这样得到的辅助平面的码表范围为(U+0000 – U+FFFFF) ,总共最多20bit -
将20bit ,分为high 10bit 与 low 10bit。high 1bit | 0xD800 得到前导代理, low 10bit | 0xDC00 得到后尾代理
从这里也可以理解为什么 在基本多语言平面中, (U+D800 ~ U+DFFF ) 要作为保留字符了
UTF-16既保留了解析速度,同时也比较节省存储空间。这个是UTF-8和UTF-32两者优点的结合。
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !