引言
之前一直都一个问题不明白,就是unicode,utf-8,utf-16,utf-32都有什么联系和区别呢,花了一点时间来查找资料,终于得到一个还算满意的答案。
unicode
首先,我们思考一下unicode是什么,到底为什么会出现?
unicode其实就是对字符的一种编码方式,可以理解为一个字符---数字的映射机制,利用一个数字即可表示一个字符。
对字符编码的想法很正常,因为计算机能够处理的是二进制码,而不是字符,所以当然要对字符进行编码咯。
所以,我们都知道的ASCII码就是干这个事情的。但是,众所周知,ASCII码只有8位,因为在设计这玩意儿的时候,咱亚洲人,还有非洲兄弟,非英语国家的兄弟都没参与进来,所以开始只要能用二进制标识英语就够了。
后面,其他语系的计算机使用者需要在电脑上使用他们的语言,那么ASCII就表示不了这么多文字了。
于是,unicode应运而生。在表示一个Unicode的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。
关于unicode,我们需要了解这样的几个重要概念。
因为unicode要表示老多的字符了,所以unicode来对应那么多字符的码肯定很多啊老多老多了
不过,在分析之前,unicode来对应字符的码叫啥来着?
码点。
没错,就是码点。码点就是unicode标识字符的那个特定的数字。
但是码点那么多,怎么管理码点呢?
unicode引入了平面机制。即将每65536个码点作为一个平面,总共有17个平面,哇,这么多,总可以表示世界上所有的字符了吧~
不过,我们最常用的字符就那么一点,所有unicode定义第一个平面为最常用的平面BMP,后面的平面呢,为增补平面。
这样区分平面也什么用呢?这就涉及到了编码问题了。
UTF-8,UTF-16,UTF-32
有了码点来表示字符,那么就考虑如何对码点进行编码了。有同学说,简单啊,不是二进制码吗,那就用二进制直接表示所有的unicode平面就行了。
上面的想法可以吗?可以的。比如UTF-32。UTF-32就是用二进制直接表示所有unicode平面。但是,想要表示所有的平面,至少需要四个字节。但是实际上,我们常用的就那个BMP平面,增补平面很少用啊。也就是说,为了很少用到的增补平面上,我们对每一个字符都要用四个字节表示,好亏啊~
为了解决这个问题,人们提出了UTF-16这种编码方案。对于BMP这个常用的平面,UTF-16用两个字节编码。而对于后面的增补平面,UTF-16引入代理区的机制来表示后面的增补平面。
代理区UTF-16 为了编码增补平面中的字符而保留的,总共有 2048 个位置,均分为高代理区(D800–DBFF)和低代理区(DC00–DFFF)两部分,utf-16对代理区进行保留,不用代理区的内容来进行两个字节的编码,而是将代理区组合为代理对来对增补平面编码。一个高代理区(即上图中的Lead(头),行)的加一个低代理区(即上图中的Trail(尾),列)的编码组成一对即是一个代理对(Surrogate Pair),必须是这种先高后低的顺序,如果出现两个高,两个低,或者先低后高,都是非法的。这样,就实现了对BMP平面可以用两个字节编码,而对于增补平面需要四个字节编码。这样,达到了节省空间的目的。而UTF-8的思路同理,有兴趣的同学可以上网查查啊~
还是没懂?不要怕,我为你们整理了一份思维导图,看导图就明白了~
全部评论
(1) 回帖