生活在中国的程序员恐怕没有不会碰到这个问题的–编码问题. unicode, utf-8, GBK, charset, encoding, code page这么一大堆术语加缩写,让人一看到就头晕,根本搞不清哪个是哪个. 各种各样的地方都会出现编码问题–数据库, JSP, mp3标签等等等等,不一而足. 我自己就花了不少时间解决编码的问题(还曾经写了一个很粗糙的Firefox的扩展来修正网页的编码),但面对这么多的术语,再加上平时解决问题时间有限,一般都是找了个方法摆脱了乱码问题之后就再也不想去看这个玩意了。今天本来是想比较一下python和ruby两个语言的,结果从ruby对unicode的支持问题开始,又回到了编码问题上来,终于决定把这些东西搞个清楚。
不过相关术语是在太多了,我建议大家先去看Unicode的词汇表,有什么疑问的词就可以在这个表里面search一下,一般可以立即得到一个清晰准确的解释,我主要结合wikipedia上对unicode的注释(unaccessible for some well-known reason)和unicode的这个词汇表讲几个最常碰到的词语和几个最大的疑惑。
confusing question:
Q: 编码到底是怎么一回事(-_-超级大问题,就解决这一个了决定)?
A: 历史上,编码问题最初是不存在的或者说不是什么大问题(很明显的,计算机发展初期只有英文使用者),字符集和字符编码是不区分的,统一用charset这个词来表示,同时兼了这两个词的含义.到了现代,编码这个问题被解耦成为几个部分:
1. what characters are available
2. their numbering
3. how those numbers are encoded as a series of “code units”
4. how those units are encoded as a stream of octets (bytes)
部分1指的就是字符集,表示可用的所有的字符,包括数字,字母,标点,汉字等等.
部分2指的是编码字符集(这里用英文可能更准确一些coded character set,被编码了的字符集),也即部分1中的每个字符会映射到一个或多个数字或者其他符号,由这些符号来代表部分1中的字符.
部分3和4指的是如何将2中映射得到的数字最终表示为计算机可以识别的二进制串(3,4拆分为两步的主要原因于计算机对字节流的解释有关big-endian or little-endian,不考虑的话应该可以合并).
从这四个部分可以看出,解决编码问题需要定义字符集,定义映射方案,定义编码方案这几个重要步骤.
Q: Unicode又是怎么一回事,它和utf-8有什么关系?
A: Unicode和另外一个与之并列的标准ISO 10646共同组成了一个上面提到的解决编码问题的解决方案,它不是四个部分中的任何一个,而是这四个部分各自解决方案的一个组合.其中字符集是由ISO 10646定义的,numbering应该在Unicode的标准中有(?^_^我也没看过,不确定).utf-8是Unicode提供的用于解决编码子问题的方案之一,同时还有utf-16和utf-32等等编码方案.
Q: code page呢?
A: code page就是coded character set,最初是IBM使用的一个术语,后来微软也大量使用.
这就是我的demystifying encoding problem, 如有不当请指教.
http://www.niyue.com
参考文献:
[1] Glossary of Unicode Terms http://www.unicode.org/glossary/
[2] Unicode in Wikipedia http://en.wikipedia.org/wiki/Unicode
[3] Character encoding in Wikipedia http://en.wikipedia.org/wiki/Character_encoding