文章目录
编码格式的由来百花齐放 - 语言差异汉文化 - GB家族大一统 - Unicode轻量化 - UTF-8为何使用UTF-8?参考文献
许多同学都知道我们在编写代码时,都有个疑问,为什么要把编码格式设置为UTF-8?UTF-8有什么好处?为什么不用默认的GBK呢?下面我们来一起来探索编码格式的奥秘。
编码格式的由来
我们都知道,计算机的运算模式是二进制的,为了表示不同的数据,我们需要规定二进制的各种组合代表不同的数据,这种规定就是编码格式,比如我设计一种编码认为1011是A,那么当计算机使用我设计的编码时,当我输入A时就会把A翻译成1011进行存储,在读取到1011时就会把它翻译成A进行展示,最开始每个公司或组织都应用着不同的编码格式,而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了ASCII编码。
ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符 。
百花齐放 - 语言差异
在英语中,用128个符号编码便可以表示所有,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号 。
但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0--127表示的符号是一样的,不一样的只是128--255的这一段。
至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号 。
汉文化 - GB家族
GB即国标的意思,像 GB2312、GBK等,都是我国为汉字编码专门指定的编码格式。
GBK编码,是在GB2312-80标准基础上的内码扩展规范,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。
GBK是采用单双字节变长编码,英文使用单字节编码,完全兼容ASCII字符编码,中文部分采用双字节编码。
大一统 - Unicode
那么问题又来了,各国自己内部编码解决了,但是各个国家的相互通信还是很麻烦的,于是乎 统一码(Unicode) 应运而生,Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
在这种语言环境下,不会再有语言的编码冲突,在同屏下,可以显示任何语言的内容,这就是Unicode的最大好处。就是将世界上所有的文字用2个字节统一进行编码。那样,像这样统一编码,2个字节就已经足够容纳世界上所有的语言的大部分文字了。而这也成为了他的缺点,我们知道在ASCII编码中,英文字母等只占一个字节,我们在使用Unicode编码类型时,如果英文内容多的情况下,将会浪费将近一半的空间,为了解决这个问题,我们的主角终于登场了,那就是UTF-8。
轻量化 - UTF-8
UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。
UTF-8使用1~4字节为每个字符编码:
一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000~U+007F)。带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。其他极少使用的语言字符使用4字节编码。
对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的;对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
转化示例 汉字 :猫 Unicode 格式 :01110011 00101011 UTF-8 格式 :11100111 10001100 10101011
扩展
UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为 “storage format”)的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。
UTF-32 (或 UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元。其它的Unicode transformation formats则使用不定长度编码。因为UTF-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得UTF-32通常会是其它编码的二到四倍。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。
为何使用UTF-8?
回到我们开始提的问题,为什么要把编码格式设置为UTF-8?UTF-8有什么好处?为什么不用默认的GBK呢?
UTF-8 是 Unicode 的实现方式之一,既有Unicode 广泛性,又比Unicode更加灵活,极大地节省了存储空间。如果是UTF-8编码,则在外国人的英文IE上也能显示中文,而无需他们下载IE的中文语言支持包。
UTF-8版本虽然具有良好的国际兼容性,但中文需要比GBK/BIG5版本多占用50%的数据库存储空间。
所以在编码格式的选择上,我们应该结合实际情况,并没有强制要求,如果我们的开发只在国内使用,不涉及其他国家语言,中文多的情况下,GBK也是不错的选择,但是如果我们也不确定以后的发展,建议还是用UTF-8稳妥些。
参考文献
【1】百度百科 - ASCII