Unicode 与 UTF

Unicode是一个字符库,里面收录了全世界绝大多数的字符,并用0,1,2,,,n对每个字符进行惟一的编号,这些编号咱们称之为码点。html

当前Unicode字符被分为17组编排,每组称为一个平面,每一个平面拥有65536(即2^16)个字符。函数

包含最前面的65536个字符,即码点范围从0 ~ 2^16 - 1,称为基本多文种平面(Basic Multilingual Plane, BMP)。全部最多见的字符都在这个平面里面,这是Unicode最早定义和公布的一个平面。剩下的16组平面称为辅助平面。编码

17组平面能够包含2^(5+16)个字符,即须要21位的编码空间,比3字节略少。设计

Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。考虑一些极端的例子: 1.用二进制代码表示Unicode中码点为1的字符,使用1个字节就是00000001;使用2个字节就是00000000 00000001;使用3个字节就是00000000 00000000 00000001;使用4个字节就是00000000 00000000 00000000 00000001。很显然若是使用四个字节存储该字符,将形成极大的空间浪费。 2.用二进制代码表示Unicode中码点为100000的字符,至少须要3个字节,即 00000001 10000110 10100000,固然也能够用4个字节00000000 00000001 10000110 10100000来表示。3d

考虑到系统平台的差别以及出于节省存储空间的因素,Unicode并无对使用多少个字节来存储一个字符对应的二进制代码作出强制的规定,所以Unicode的实现方式有多种,而Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)code

咱们平时常见的编码方案,好比ASCII、UTF-八、UTF-1六、UTF-32都是对Unicode的不一样实现。 ASCII编码:使用1个字节来表示一个字符,该编码方案仅适用于对Unicode中的前128位字符,适用于西文文档。 UTF-32编码:使用4个字节表示一个字符,理论上4个字节可表示2^32 = 4,294,967,296,远超当今的Unicode所接纳的字符,所以能够彻底对应Unicode编码。该编码的优势是转换规则简单直观,查找效率高,可是也有致命的缺点,浪费空间,一样内容的英语文本,它会比ASCII编码大四倍,目前基本上没有什么场景去使用这种编码方式。 UTF-8编码:在衡量一个程序设计好坏时,时间和空间这两个维度的复杂度是永远绕不开的。若是你内存足够大,你彻底能够用空间换时间,可是从编码设计角度来讲,人们真正须要的仍是一种节省空间的编码方案,这直接致使了目前使用最多的utf-8编码方案的诞生。UTF-8是一种变长的编码方法,字符长度从1个字节到4个字节不等。越是经常使用的字符,字节越短,最前面的128个字符,只使用1个字节表示,与ASCII码彻底相同(为了方便书写,后面涉及到的二级制代码统一用16进制表示)。orm

UTF-16编码:介于UTF-32与UTF-8之间,同时结合了定长和变长两种编码方法的特色。它的编码规则很简单,基本平面的字符占用2个字节,辅助平面的字符占用4个字节。也就是说,UTF-16的编码长度要么是2个字节(U+0000到U+FFFF),要么是4个字节(U+010000到U+10FFFF)。前面介绍过了基本平面包含了 65536 = 2^16 个字符,所以用两个字节去表示很是合适。cdn

那么紧接着问题就来了,计算机怎么知道当前的这个字符,它应该读取两个字节仍是四个字节呢?下面具体来讲对应的解决方案。具体来讲,辅助平面的字符位共有2^20(即 2^4(辅助平面个数) x 2^16(每一个辅助平面理论上可容纳的字符个数))个,就是说,对应这些字符至少须要20个二进制位。UTF-16将这20位拆成两半,前10位映射在U+D800到U+DBFF(即56319 - 55296 = 2^10,空间大小2^10),称为高位(H),后10位映射在U+DC00到U+DFFF(计算同前面的高位,空间大小2^10),称为低位(L)。这意味着,一个辅助平面的字符,被拆成两个基本平面的字符表示。当咱们遇到两个字节,发现它的码点在U+D800到U+DBFF之间,就能够判定: 1.紧跟在后面的两个字节的码点,应该在U+DC00到U+DFFF之间 2.这四个字节必须放在一块儿解读htm

因为历史的缘由,JavaScript使用UCS-2编码,该编码方案使用2个字节表示一个字符。该编码方案对于Unicode中大于2个字节的字符处理带了不少的局限性,好比一个占用4个字节的字符,若是用使用UCS-2编码方案处理,会被处理为两个字符,这会致使字符串的长度以及使用字符相关的函数,都没法获得正确的返回结果,要想获得正确的结果,必须使用polyfill部署本身的版本。blog

主要参考阮一峰的博客http://www.ruanyifeng.com/blog/2014/12/unicode.html

相关文章
相关标签/搜索