一种对汉字更环保的 Unicode 编码方案
Windows 早期默认支持的中文编码方案是 GBK ,它是对早期 GB2312 的一个扩展。后来国家又发布了 GB18030 标准,扩展了 GBK ,增加了一些 Unicode 里才有的汉字,这样就可以做到和 Unicode 字符集做完全的映射了。
而后来 Unicode 逐渐成为标准,几乎所有的系统处理多国语言时,都把 Unicode 做为默认设置了。Unicode 有两套编码集,UCS-2 和 UCS-4 ,后者是对前者的补充,虽说字面说写的 4,但实际上只用到了 3 个字节不到。
Windows 的内部其实是用的 UCS-2 标准,并用 UTF-16 来实现。而非 Windows 系统大多采用了 UTF-8 。UTF-8 在很多情况下更有优势,首先它不需要考虑大头小头的问题,其次,数据损坏的时候,不会有半个汉字的问题。并且 UTF-8 可以完整的表达 UCS-4 而不需要有额外的付出。
前几年,处于 Windows 程序员转型期,经过一些痛苦的实践,我终于意识到,VC 提倡的所谓为软件维护 UNICODE 和 非 UNICODE 两个版本是件巨傻 X 的事情。之后,我们的程序再也不为内码分版本了,一律采用 UTF-8 。
不过,UTF-8 的设计明显是用英文为主的西方人搞出来的东西。对于中文一点都不环保。所有汉字和中文标点都需要 3 个字节才能表达。而少量欧洲字母可以用 2 字节表达,英文的 ASCII 符号则可以只用单字节。
我不指责这个设计,因为兼容 ASCII 是 UTF-8 的最大优势。其它,则是 KISS 原则下的产物。
不过,若是内部使用的话,如果你介意这 1/3 的储存空间的浪费的话,是不是有改进的余地呢?下面我们来讨论这个问题。
观察 Unicode 的码表我们可以发现,实际大部分汉字是从 U+4E00 开始编码的,到 U+9FFF 结束。U+2000 到 U+3FFF 则有一些汉字标点符号等。稍加设计,我们可以定义出一种编码方案,对 UCS-2 或 UCS-4 做编码,让汉字可以用双字节表达,并保持对 ASCII 的兼容(U+0000 到 U+007F)段依然使用单字节。
作为牺牲,那些欧洲字母和韩文,就委屈到 3 字节甚至更长的编码了。
简述一下对 UCS-2 的编码方案(UCS-4 只需要做点小扩展)。
使用 大头方案(Big-endian)
ASCII 部分 U+0000 到 U+007F 保留,用单字节 0x00 ~ 0x7f 表达。
对于 U+2000 到 U+9FFF ,除掉其中的 U+3F00 到 U+3FFF 部分(目前这个部分为空),做一个简单变换:即加上 0x6000 ,把编码转换到 0x8000 到 0xffff 部分。做双字节编码。由于 U+3F00 到 U+3FFFF 被除外(如果是 UCS-4 可以去除 U+3E00 到 U+3FFF),所以 0x9f 将成为一个 magic number 。
对于其它部分:U+0080 到 U+1FFF ,U+3F00 到 U+3FFF ,U+A000 到 U+FFFF ,一律编码到第 2 3 字节。并将第一字节直接设为 0x9F 。
这样,解码成 UCS-2 的算法非常简单(甚至不比 UTF-8 解码更复杂)。缺点是,缺乏 UTF-8 的容错性,有半个汉字的隐患。
这样的编码什么时候会有用?
网络传输时,对字符串做这样的编码(写一个 UTF-8 到这个特定编码方案的互转程序可以在 10 行 C 代码内完成,并非常高效),可以有效减少传输的数据。
如果需要做大规模的数据储存,比如搜索引擎抓取的网页时,可以节省不少储存空间。
至于源代码,和配置文件中,还是推荐使用 UTF-8 ,毕竟编辑器的支持更重要。
Comments
Posted by: 福利工口姬 | (38) April 16, 2014 04:23 PM
Posted by: daniel | (37) November 3, 2011 11:05 PM
Posted by: 桂林旅游 | (36) May 24, 2009 05:05 PM
Posted by: RedNax | (35) March 4, 2009 06:10 PM
Posted by: Cloud | (34) January 8, 2009 01:26 PM
Posted by: Samuel | (33) January 8, 2009 04:49 AM
Posted by: Samuel | (32) January 8, 2009 02:10 AM
Posted by: Cloud | (31) January 6, 2009 02:01 AM
Posted by: 桂林旅游 | (30) January 6, 2009 12:15 AM
Posted by: Anonymous | (29) December 26, 2008 10:41 AM
Posted by: Sutra | (28) December 25, 2008 11:55 PM
Posted by: Anonymous | (27) December 25, 2008 11:31 PM
Posted by: Bennie | (26) December 25, 2008 11:51 AM
Posted by: black | (25) December 25, 2008 02:13 AM
Posted by: Cloud | (24) December 24, 2008 06:44 PM
Posted by: 微子 | (23) December 24, 2008 06:24 PM
Posted by: Cloud | (22) December 24, 2008 05:30 PM
Posted by: AleTiff | (21) December 24, 2008 04:37 PM
Posted by: Googol | (20) December 24, 2008 04:09 PM
Posted by: Googol | (19) December 24, 2008 04:01 PM
Posted by: Slash | (18) December 24, 2008 03:21 PM
Posted by: smallfish | (17) December 24, 2008 03:20 PM
Posted by: 星际工作室 | (16) December 24, 2008 03:04 PM
Posted by: cat | (15) December 24, 2008 02:48 PM
Posted by: Cloud | (14) December 24, 2008 02:15 PM
Posted by: alioxp | (13) December 24, 2008 02:02 PM
Posted by: H | (12) December 24, 2008 01:16 PM
Posted by: cx | (11) December 24, 2008 12:59 PM
Posted by: qingbo | (10) December 24, 2008 11:49 AM
Posted by: Anonymous | (9) December 24, 2008 11:06 AM
Posted by: analyst | (8) December 24, 2008 11:01 AM
Posted by: 王者之剑 | (7) December 24, 2008 10:16 AM
Posted by: Rain | (6) December 24, 2008 10:12 AM
Posted by: 2008-12-24 | (5) December 24, 2008 10:01 AM
Posted by: Cloud | (4) December 24, 2008 02:30 AM
Posted by: 微子 | (3) December 24, 2008 01:36 AM
Posted by: Cloud | (2) December 24, 2008 12:31 AM
Posted by: 最大的 | (1) December 24, 2008 12:02 AM