Unicode 和 UTF-8 的关系
曾经这个世界上,有着gb2312,gbk,latin1,utf 等各种字符集,现在,我们也能不时的看到他们的身影.
但是值得庆幸的事,时过境迁,这些主要的字符集,都已经逐渐被utf8取代.
但是我们很多新人,还是搞不清楚,unicode和utf8的关系,为啥还有utf16等问题也时常困扰着他们.
业界有一个大牛,写了一个文章:
http://huoding.com/2015/10/13/472 (Unicode and UTF-8)
然而说的也是比较细节,讲了一些查询的方法和函数. 实际操作中,可以参考
最核心的区别和问题,我列在这里:
广义的Unicode 是字符集, 是对字符的按槽放入的规范,狭义的unicode一般是指utf16,实际上也是一种编码方式
而utf8是对unicode进行变长编码的编码方式,仅仅是一种编码方式
其他编码,如gbk,gb2312,实际上既是字符集,也同时就规定了编码方式.为啥unicode和utf8存在这个不同的呢?
请看下文:
Unicode预订的编码空间大小为0x0-0x10FFFF,最多可以容纳1114112(100多万)个字符
实际上并不能使用这么多的空间,于是编码方式出现了两种,ucs-2(BMP)和ucs-4 编码方式
其中,bmp是Basic Multilingual Plane的简写.
一个字符的Unicode编码(码点)是唯一确定的,但由于不同系统平台实现方式的不同(如字节序的不同),或基于传输或节省存储空间等各种因素考 虑,Unicode的实现方式各不相同,Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为UTF)
如UTF-16
UTF-16采用双字节对UCS-2字符进行编码,由于UCS-2本身也是双字节编码,故一般UTF-16编码和UCS-2编码可等同对待,但由于不同平台对字节序的理解不同,
UTF-16又分为UTF-16 BE(Big-Endian, 简写为UTF-16 BE)和UTF-16 LE(Little-Endian,简写为UTF-16 LE)两种编码方式.
UTF-16编码的优点:编码效率高,寻址快。
由于所有字符都采用双字节编码,可以快速对字符进行定位及计算,如一个文本文件,可以通过获得其文件大小/2即可计算得知包含的字符数。Java默认使用UTF-16 BE编码。
那么为什么会出现utf-8呢:
1)、和ASCII码不兼容,而且不太好移植(Not Portable)
例如:char *s=“Good ,北京”;该C语言代码采用UTF-16编码后,字节序列中间有许多’\0’,’\0’ 会被识别为字符串的终止,strlen()函数不起用了。
2)、存储空间较大,造成存储及带宽的极大浪费
极端情况下,英文存储空间会Double!
为了解决这些现实生活中遇到的问题,UTF-8编码应运而生!
言归正传,对于UTF-8
UTF-8是针对Unicode(UCS-2或UCS-4)的可变长度编码方式,是一种前缀码,它可用来编码Unicode中的任何一个字符。UTF-8
编码和ASCII码全兼容,自应用以来逐渐成为电子邮件、网页及其他存储或传送文字应用中,最优先采用的Unicode编码方式。
如果有兴趣,可以延伸阅读RFC:
http://www.rfc-editor.org/rfc/rfc3629.txt