字符集与编码(一)——charset vs encoding

注:因为两边同步的麻烦,更多更改及调整可参考个人网站:xiaogd.net 上的字符集编码与乱码系列,已将字符集编码系列与乱码探源系列合并,更新及勘误等再也不更新到这边。html

许多时候,字符集与编码这两个概念常被混为一谈,但二者是有差异的,做为深刻理解的第一步,首先要明确:网站

字符集字符集编码是两个不一样层面的概念

  • charset是character set的简写,即字符集ui

  • encoding是charset encoding的简写,即字符集编码,简称编码编码

与接口及接口实现的对比

能够把这二者与接口接口实现作个对比:spa

从这里能够很清楚地看到,.net

  1. 编码是依赖于字符集的,就像代码中的接口实现依赖于接口同样;code

  2. 一个字符集能够有多个编码实现,就像一个接口能够有多个实现类同样。xml

具体例子及规范用法

能够简单看两个例子,一个自于html文件,用的是charset:htm

<meta http-equiv="content-type" content="text/html;charset=utf-8">

另外一个来自于xml文件,用的是encoding:接口

<?xml version="1.0" encoding="UTF-8"?>

哪种用法更规范呢?显然是后者,它更加准确地区分了字符集与编码的概念。

“charset=utf-8”容易让人误解为存在一种叫“UTF-8”的字符集,但实际上,不管是UTF-8仍是UTF-16,UTF-32都是对同一种字符集的不一样编码实现而已。

为何要严格区分字符集编码这两个概念?

字符集编码一对一的情形

有不少的字符编码方案,一个字符集只有惟一一个编码实现,二者是一一对应的。好比GB2312,这种状况,不管你怎么去称呼它们,好比“GB2312编码”,“GB2312字符集”,说来讲去其实都是一个东西,可能它自己就没有特地去作什么区分,因此不管怎么说都不会错。

为何一对一是一种广泛的状况呢?

咱们以GB2312为例,GB=Guo Biao=国标=国家标准,标准出来原本就为了统一,你一个标准弄出N个编码实现来,你让人家用哪一个呢?

字符集编码一对多的情形

事情到了Unicode这里,变得不同了,惟一的Unicode字符集对应了三种编码:UTF-8,UTF-16,UTF-32。若是仍是这么笼统地去称呼,就很容易搞混了。

为何Unicode这么特殊?

人们弄出新的字符集标准,驱动力无外乎是旧的字符集里的字符不够用了。

Unicode的目标是统一全部的字符集,囊括全部的字符,因此字符集发展到它这里就到头了,再去整什么新的字符集就不必也不该该了。

但若是以为它现有的编码方案不太好呢?在不能弄出新的字符集状况下,只能在编码方面作文章了,因而就有了多个实现,这样一来传统的一一对应关系就打破了。

咱们严格地区分字符集与编码两个概念,理由就在这里。

指定了编码,它所对应的字符集天然就指定了,编码才是咱们最终要关心的。

Unicode早期与如今的对比

让咱们来看一个图,它展示了Unicode早期与如今的一些差异:

注:因为历史方面的缘由,你还会在很多地方看到把Unicode和UTF-8混在一块的状况,这种状况下的Unicode一般就是UTF-16或者是更早的UCS-2编码,在后面的篇章中咱们会进一步分析。

下面是“记事本程序”保存时的一个截图,是Unicode的一个不规范使用,这里的Unicode就是指UTF-16:

image

咱们如今说了很多Unicode,因为各类缘由,必须认可,在不一样的语境下,“Unicode”这个词有着不一样的含义,它可能指:

  • Unicode标准

  • Unicode字符集

  • Unicode的抽象编码(编号),也即码点(code point)

  • Unicode的一个具体编码实现,一般即为变长的UTF-16(16或32位),又或者是更早期的定长16位的UCS-2

关于这些话题在后面的篇章里会作进一步探讨。