空间有形 梦想无限

hi,it's onebird‘s blog。My homepage is onebird.net.

中文编码处理(1) -- 编码与字符集

onebird | 24 八月, 2006 01:33

-->编码 字符集 中文编码

关于编码问题 我总结一下我的理解
大家纠正一下我的理解差

字符集 charcterset 字符的集合
字符编码 Encoding 如何将二进制数据识别为字符的编码

理论上它们是分开的,一种编码表示的字符式有限的,常常一种编码
设计为表示一种字符集。 如既有GBK GB2312字符集 又有GBK GB23122312
这样造成 经常误解释为 一种字符集一般也对应了一种编码。

再举例
Unicode使一种字符集
UTF-8 UTF-16是两种编码,他们能够表示Unicode字符集的所有字符。
为什么有两种呢 因为UTF-8使用短编码表示大量使用的英文 用长编码表示较少使用的日语 韩语什么的
Unicode字符集包含所有GB2312的字符 ,显然用UTF8或UTF16编码也能表示编码所有的GB2312字符集里的字符
那么我们说UTF8编码了GB212字符集
而GBK字符集的字符是GB2312字符集的阔充 所以GB2312编码既然编码了所有GB212字符
那GBK编码也能表示所有GB2312字符 ,当然编码的方式不一样。(同一个字对应的二进制编码不一样)

举例
香蕉是个大笨蛋 这6个字符是我定义的aka字符集

下面是我定义的 zixia 编码方案 可以看到它的编码中表示了aka字符集的所有字符
北 10000001
京 10000010
香 00000001
蕉 00000010
是 00000100
个 00001000
大 00010000
笨 00100000
蛋 01000000
中 10000100
国 10001000

所以我们说zixia编码可以表示aka字符集

编码转换
为什么有编码转换这个问题
因为信息表示总是用2进制表示的,对计算机而言其实所有文件都是二进制文件。
所谓文本文件 就是我们按一定编码方式将二进制数据表示为对应的文本
如 00000001000000100000010000001000000100000010000001000000
这样的文件。我用一个支持zixia编码的记事本打开,它就按照编码方案显示为
香蕉是个大笨蛋

如果我把这些字符按照 GBK另一个文件 那么则肯定不是这个 而是
1100111111100011 1011110110110110 1100101011000111 1011100011110110 1011010011110011 1011000110111111 1011010110110000 110100001010

如果我们读不同编码的文件 到程序内部处理再保存程另一个文件 涉及到三次编码问题
1 读入文件使用什么编码
2 程序中使用什么编码(Fixme here)
3 写出文件使用什么编码

其中2 3 程序中使用什么编码可以按照系统或者开发工具默认编码(Fix me here)处理
或者自己指定编码

但是1中 如果为知编码的一个文件 按照什么编码读近来 结果大相径庭
而且有些编码无法表示一些字符。
比如记事本实现就是按照系统默认编码读入 当读入utf编码的的文件时候就有部分字符集不能表示
而UltraEdit就使用了先读入字节流根据二进制数据用一些算法进行判断(Identify Encoding 文章)
所一能够使用相应编码读入。

coreSearch内部为什么要使用utf8编码?

如果我们每次要处理的文件只有一种字符集 并且我们能都判断出
那么我们仅仅需要能支持该字符集的编码。如上的 aka字符集我们使用zixia编码 GBK GB2312编码都行
而GB2312编码 我们使用GBK GB2312 utf8编码都行。

但是如果处理的文件中 既包括GBK中文编码 又包括EUC-JP日语的编码 那么我们必须选择一种编码
它能支持这两个字符集 utf8编码支持的unicode字符集能够涵盖了的字符最多 我们使用utf8的话
就能适应这种情况

当然使用utf8 utf16都可以(如果在中文检索应用比较多的情况下 使用utf16有更高的空间效率)
同样的 如果仅仅检索中文gbk编码也够了 应为gbk编码包含了几乎所有的中文字符了(包括简体繁体)。

评论

Re: 中文编码处理(1) -- 编码与字符集

momo | 24/08/2006, 01:55

解除了我一直以来的误区啊……
前几天导数据库,从 mysql4 转入 mysql5,怎么弄都是乱码,早知道程序的三次编码原理就少走弯路啦。

发表评论