请选择 进入手机版 | 继续访问电脑版

北大中文论坛 www.pkucn.com

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 18358|回复: 30

GB18030,想说爱你不容易

[复制链接]
发表于 2006-5-23 16:55:29 | 显示全部楼层 |阅读模式
  GB18030,想说爱你不容易


  之所以会有此感叹,并非觉得GB18030的编码框架有什么不妥,而是对该标准在实际应用中遇到的尴尬情形的一些个人看法。

  疑惑一:GB18030到底是一种ANSI编码还是Unicode编码?这本来是毫无疑问的,作为对GB2312和GBK的扩展,GB18030势必要向下兼容这两个编码标准,而GB2312和GBK都是不折不扣的ANSI编码,那么建立在这两个标准基础之上的GB18020也理所当然的应该是一种多字节的ANSI编码了。

  既然是ANSI编码,那么在实际的系统中,它就应该是作为一种本地化的编码字符集出现的。比如在Windows里面,它就应该像GBK、Big5这些ANSI编码那样,有自己的代码页和相应的代码页属性(主要指引导字节和尾随字节的取值范围)。对于代码页,微软已经给出了答案:Win2k以上的操作系统只要安装了微软的GB18030-2000扩展支持包,就可以支持GB18020-2000编码标准的54936代码页了。我在安装了18030支持包之后,根据微软给出的测试建议,写了个调用API函数IsValidCodePage(54936)的小程序,测试结果是54936代码页可用(未安装18030支持包以前,测试54936代码页不可用)。

  但仅仅是某个代码页可用并不表示文本处理程序就可以处理基于该代码页编码的文本了,还必须把这个代码页设为系统的当前代码页才行。可是,18030扩展包不是自带了一个GB18030?Unicode的文本编码转换程序的嘛,这个程序并不需要把系统的当前代码页设为54936就可以工作呀。其实,关于这一点花点时间想一下也很简单:文本文件的内码转换其实根本不需要操作系统的支持,这种转码工作在计算机文本处理任务中来说算是最简单的了――说得极端一点,只要有转码表,我们甚至可以写一个在DOS下运行的GB18030?Unicode转码程序,如果省去中文界面的话,这个程序连中文系统都不用加载。在现实应用中,文本处理工作远不只转码这一项,就拿日常用得比较多的文本编辑来说吧――假设有一款以ANSI方式来处理文本的字处理软件,如果想要在这个软件中正确显示和编辑GB18030编码的文本的话,首先就应该把系统的当前代码页设为54936才行。这是因为代表GBK的936代码页的属性和代表GB18030的54936代码页的属性有很大的不同,在936代码页下,ANSI程序是无法正确处理GB18030编码的文本的。

  那么把系统的当前代码页设为54936不就好了吗?可是事情好像并没有那么简单……在编程时,通过调用API函数GetACP可以获得系统当前的代码页,可是Win32 API里面并没有对应提供一个类似"SetACP"这样的设置当前代码页的函数。事实上即使是Windows自己,也没有办法直接改变系统当前的代码页,改变当前代码页的方法是在控制面板中设置区域和语言选项,然后重启才能生效。Windows区域和语言选项里面的"非Unicode程序语言版本"设置对于普通电脑用户来说就是为那些只能处理特定语言的程序(ANSI文本处理程序)指定一个正确的,默认可以处理的语言种类(比如是中文、日文或韩文);而对于开发ANSI文本处理程序的程序员来说,其实就是设置系统当前的代码页。比如要设置950代码页的时候,选"中文(台湾)",要设置936代码页的时候,就选"中文(中国)"。可是让人难以理解的是,在安装了18030支持包以后,"代码页转换表"里面已经显示"54936(GB18030 简体中文)"代码页是可用使用的了。但在"非Unicode程序语言版本"列表里面,却没有相应地提供一个类似"中文(中国GB18030)"这样的选项,也就是说:Windows根本就没有提供给我们把代表GB18030编码标准的54936代码页设为系统当前代码页的选择。难道微软并不认为GB18030是一种ANSI编码,不需要相应的代码页支持?可是这个结论显然跟微软提供了54936这个代码页是相矛盾的,因为代码页本身就是处理不同本地化语言的一种机制,生来就是为ANSI编码而设的。而且18030支持包里面的ReadMe文档也透露了它附带的转码程序其实是调用了API函数MultiByteToWideChar和WideCharToMultiByte来实现的(否则无法解释这个程序怎么会只有区区25KB之小),这就是说微软确实是把GB18030当作一种多字节的ANSI编码来看待的。可是现在这个编码的代码页却根本不能设置为系统的当前代码页!这恐怕在Windows所支持的所有代码页里面,是唯一的一个吧。

  疑惑二:54936代码页的真相?既然CP54936在所有的代码页中显得如此之特殊,这不得不让人产生了一窥其具体技术细节的欲望。我们知道:对于代码页机制来说,不同代码页间的主要区别在于各个位置上的字节取值范围的不同。比如CP936的引导字节范围在0x81-0xFE之间,尾随字节范围在0x40-0x7E或0x80-0xFE之间;CP932的引导字节范围在0x81-0x9F或0xE0-0xFC之间,尾随字节范围在0x40-0xFC(0x7F除外)之间。显然CP936和CP932有很大的不同,这种不同成了系统在当前代码页下,区分哪些是有效编码(字符)和无效编码(字符)的依据。言归正传,虽然Windows需要重启才能改变当前代码页,但要查看某个代码页的信息却不用那么麻烦。在任意一个代码页下,随时都可以用API函数GetCPInfo读出包括当前代码页在内的所有系统支持的代码页的属性信息。我们先用最熟悉的CP936试看看,测试结果GetCPInfo返回的信息如下:MaxCharSize=2;LeadByte={81,FE,00,00,00,00,00,00,00,00,00,00}。这个结果的意思是说:CP936的字符最大编码长度是两个字节,它的引导字节有一个取值范围:0x81-0xFE。显然GetCPInfo(936)返回的信息跟我们所了解的GBK编码标准的技术框架是符合的。接下来看看我们所关心的CP54936的情况,测试结果GetCPInfo返回的信息如下:MaxCharSize=4;LeadByte={00,00,00,00,00,00,00,00,00,00,00,00}。按照Windows代码页机制的说法,这个结果意味着CP54936没有引导字节取值范围的定义,而这种情况通常只有单字节ANSI编码才会出现。难怪Windows没有提供把54936设为系统当前代码页的选项了,因为即使把CP54936设为当前代码页,那些ANSI字处理程序(也就是非Unicode程序)也是无法显示和编辑GB18030编码的文本的。这一点可以很容易地从Windows的代码页技术原理上分析得到:CP54936没有定义引导字节的取值范围,但它本身又是一种ANSI编码的代码页,所以当系统运行在这个代码页下的时候,实际上等于是运行在单字节ANSI编码的代码页下面。这样一来,当我们试图在ANSI程序里面显示一个四字节编码的GB18030字符的时候,系统会毫不客气地把它识别为无效编码(字符),实际显示出来的就是一堆的问号了。这是因为单字节ANSI编码的每个字节取值都不会超过0x7F的,而GB18030的四字节编码的第一、三个字节的取值都在0x81以上,根据Windows代码页的技术规则,当然会被判定为无效编码(字符)了。

  注:Windows的代码页技术原理并不难理解。系统里面对应不同的代码页存储了不同的代码页属性――包括这个代码页所代表的编码标准的最大字符存储长度(单位:字节);引导字节取值范围;尾随字节取值范围(这个是隐藏的,用GetCPInfo函数是得不到它的,但它确实存在,看来微软还是习惯性地留了一手)。系统存储这些代码页属性最主要的目的就是用来判断某个给定的字符串里面是否包含有不符合当前代码页编码框架的字符(编码),当然这种判定是对于那些准备要送去给程序中需要显示在用户界面上的字符串(文本)而言的。对于发生在计算机内部(内存)里面的文本处理过程(比如文本文件的内码转换),是不需要进行这种判断的。这也就是为什么说文本文件的转码不需要特定系统的支持的原因。系统判断有效编码(字符)和无效编码(字符)的过程是这样的:顺序读取字符串中每个字节值,如果出现一个取值不在当前代码页属性许可的取值范围(比如在单字节代码页中出现大于0x7F的字节)内的字节的话,那么这个字节所属的字符就是无效字符,在软件界面上就会被显示为问号。对于双字节编码的代码页(Windows支持的代码页都是单字节或双字节代码页,只有CP54936是四字节这个例外),如果读出的某个字节值小于等于0x7F,就说明它是一个单字节字符;如果读出的字节值大于0x7F,就把它当成引导字节处理,看看这个字节值是否在当前代码页指定的引导字节取值范围内,以及它的下一个字节值是否在当前代码页指定的尾随字节取值范围内。如果这两个条件都成立,说明当前读到的这个字节和它的下一个字节组成了一个有效的双字节字符,否则当前字节值判为无效编码,显示为问号。

  上述这个判定过程是真实存在的,完整的编码有效性判定工作需要引导字节取值范围和尾随字节取值范围两个基本信息的支持。只是不知道微软出于什么原因,只开放了引导字节取值范围,但从Windows在文本处理上的一些行为中,是可以发现尾随字节取值范围信息是肯定存在的。比如,在简体中文系统下(CP936)写一个ANSI的小程序:这个程序的界面包括一个Edit控件和一个Button控件(两个控件的字体属性已经设置成了"宋体-18030"),编写Button控件的鼠标单击过程实现把一个编码字节值序列为<82 34 84 34>的ANSI字符串赋值给那个Edit控件让它显示"䢎"(0x82348434是CJK ExtA汉字"䢎"的GB18030编码)这个字的功能。做这个实验程序的目的是要测试在CP936代码页下,ANSI程序是否能支持GB18030编码字符的显示和编辑。该程序的运行结果是,按下Button按钮之后,Edit编辑框里面并没有如希望的那样显示"䢎",而是??。显然Windows认为在当前代码页(CP936)下面,0x82348434是两个非法字符。因为这个编码字节序列由四个字节组成,当系统读出第一个字节0x82的时候,因为这个字节值大于0x7F,所以需要判断它和下一个字节0x34能否组成一个双字节字符,而由于0x34不在GBK尾随字节取值范围之内,所以第一和第二字节被判定为无效编码;而第三字节的0x84和第四字节的0x34也是一样的。所以这四个字节组成的编码序列被判定为两个无效字符,在软件界面(Edit控件)上被显示成了两个问号。系统的这一处理结果反映了尾随字节取值范围信息的真实存在,否则很难想象它怎么会把0x8234判断为无效字符。因为根据双字节ANSI编码框架的一般规则:组成双字节字符的前后两个字节中,第一个字节必须大于0x7F以便文本处理程序把这个字节和单字节字符编码区分开来。而对第二个字节的取值范围并不作特别的规定,可以是任意取值范围(包括小于等于0x7F的ASCII编码值范围)。如果系统中没有存储GBK尾随字节取值范围定义的话,由于第一个字节0x82已经符合GBK引导字节取值范围的要求了,第二个字节不管取什么值都应该判定这两个字节组成的字符是有效的双字节字符。而事实是Windows准确地判断出了0x8234不符合GBK的双字节编码框架,这只能说明它是清楚地知道GBK的尾随字节取值范围定义的。

  实验分析到这里,结论已经很明显了:在目前正式发行的Windows操作系统,包括微软声称能支持GB18030的Win2k、WinXP和Win2003中,即使安装了GB18030-2000扩展支持包,也不能真正使这些系统支持GB18030编码标准。因为道理再简单不过了,程序员根本就没有办法编写出能在这些系统下显示和编辑GB18030-2000四字节编码文本的ANSI文本处理程序。不是很清楚这些系统是怎么通过GB18030-2000的标准符合性测试的。因为这些产品并不完全符合其中的"体系正确性:产品必须能够正确识别和处理按照国家标准GB 18030进行编码的文本文件。"这项要求。而微软提供的GB18030支持包充其量只是提供了一个字体和几个修改过的字符编码转换API函数,以及一个无法使用的CP54936,最后用一个其实跟系统支不支持GB18030标准并没有关系的内码转换小程序就蒙混过关了。

  为什么GB18030制定出来已经6年了,却一直没有得到有效的应用?为什么我们大部分的应用程序还只能停留在处理GBK字符集的阶段?为什么当我们很多公民在电脑中录入自己包含生僻字的姓名时仍然只能用×来代替?其实这并不怪GB18030-2000的编码技术框架不好,而是相关部门在推广应用该标准上虎头蛇尾的态度造成的。单以编码框架而言,虽然一直被很多人视为Unicode/ISO10646的中国版(实际上也是)。但技术上还是有它自己独到之处的,即使它的四字节编码框架跟传统的单/双字节ANSI编码相比显得不是那么的标准,但还不至于另类到无法处理的地步。个人认为它的四字节编码格式跟UTF-16编码格式的代理对机制在处理思想上很有些相似之处,从应用层来说,单独某款软件要识别和处理这种单、双、四字节混合编码并不困难。但要把这些技术融入到整个操作系统之中,并不是简单地修改几个API就能完成的,单是把Win32 API里面所有有关Ansi字符串处理的函数列出来就够吓人一跳的了。因为微软不可能单为了一个GB18030放弃其他的ANSI编码标准,加入对GB18030的支持必须是确保兼容原有的代码页机制的前提下才能实施的。而要保证这一点,就必须对几乎所有的字符串处理API进行一定的修改。总之以当年的情形,微软是很难在短时间之内拿出完整的解决方案的。政府压得急,微软草草地拿出了个换汤不换药的支持包应付了事,没想到还真通过了。也不知道政府是不是真的不清楚这个支持包的底细,反正自从这场"GB18030-2000标准之争"以微软推出扩展支持包这个皆大欢喜的体面方式收场之后,双方好像就没把推广应用这回事放心上了。几年中就一直任由应用层面上这种不尴不尬的局面持续下来,把一班满心期待迎接GB18030时代却又不明就里的中国应用开发人员撩在了一边。这些人在经过了几次徒劳的尝试之后,终于还是放弃了支持GB18030标准的念头,要么退回到GBK的小窝,要么踏上了Unicode未知的前程。总之在大家看来结论都是一样的:对于Windows,GB18030是不可用的。

  最近听说新版的GB18030-2005已经于去年年底制定出来了,虽然尚未有幸一睹标准原文真容,但希望它不会步GB18030-2000的后尘。落个不尴不尬的局面吧,因然从长远来说主流肯定是Unicode,但短期内仍然还是ANSI和Unicode并存的局面。像GB18030这种本地化版本的Unicode还是需要的。希望它的应用价值不要被再度埋没了。虽然这不是我这种小人物的努力就可以决定的。



  注:本文的测试分析结果是在NT类Win32平台上得出的,所用的开发工具是Delphi7。仅代表个人观点,其他系统平台未必如此。对于使用其他软件开发工具,或其他操作系统平台的朋友,如果有不同的实验结果和观点,欢迎拿出来大家共同讨论、分享。

[ 本帖最后由 韦剑 于 2006-5-23 16:58 编辑 ]
发表于 2006-5-23 19:16:27 | 显示全部楼层
写得很好,顶
发表于 2006-5-24 01:07:27 | 显示全部楼层
那就是说现在在VB, VC++ 这类程序是不可能出现CJK ExtA 或者CJK ExtB 字符吧?
发表于 2006-5-24 01:12:35 | 显示全部楼层
哦,原来如
中国 人又一次被鬼子愚弄了,悲哀中……
发表于 2006-5-24 07:12:50 | 显示全部楼层
GB18030其实是“政治上正确”的产物,而微软的做法也是无可指责的。

GB18030一方面向下兼容ASCII、GB2312和GBK,另一方面跟Unicode同步。从GB1300采纳UNICODE 2.1开始,中国就承诺,不管UNICODE如何调整,中国都会相应的采用。GB18030-2000跟UNICODE 3.0同步,包括了CJK EXT-A。估计下一个版本会包括EXT-B。同时,GB18030还为BMP以及其他所有的16个UNICODE平面留足了空间。那么,不管将来GB18030的版本如何调整,增加的部分跟UNICODE是没有区别的。

这样看来,WINDOWS已经有了GBK代码页,而GBK以外的东西无非是UNICODE,差别只是在向下兼容时发生的一些调整,无非是一个码位转换问题,跟UTF8-16-32之间的转换也差不了多少。那么微软为什么要多此一举自找麻烦呢?

这种政治上正确的做法,其实并不难理解。比如国际法方面,联合国通过的国际法,必须要成员国签字才能在成员国生效。我们可以把GB18030看成中国采用UNICODE的一个签字文件,Windows有了中国政府签过字的“文件”,就“合法”了。程序员为什么要爱GB18030呢?因为那是一个能让程序员写的程序合法化的文件,那么,程序员们为什么不照微软画葫芦呢?写程序的时候用GBK和UNICODE,将码位转换器加进去,就声称自己支持了。这个年头,程序员说的话算数。对我们普通用户来说,使用你的软件,能看得见汉字就行了。
 楼主| 发表于 2006-5-24 08:16:07 | 显示全部楼层

非也,ANSI和Unicode是不同的,大多数主流开发工具都可以开发Unicode程序

那就是说现在在VB, VC++ 这类程序是不可能出现CJK ExtA 或者CJK ExtB 字符吧?

extc朋友可能有些误会,我在这篇文章里面提到的测试程序都是按照ANSI的方式来处理文本的(这是因为GB18030本质上是一种ANSI编码),测试结果是Windows下的ANSI程序无法实现对GB18030的支持。
但Unicode就不一样了,目前主流的开发工具如Delphi、C++Builder、VC、VB等都能提供对Unicode开发良好的支持。按照Unicode的方式来处理文本的话,显示CJK ExtA 或者CJK ExtB 字符是没有任何问题的。
发表于 2006-5-24 08:18:08 | 显示全部楼层
这种事,不是某个程序员的问题,也不是微软的问题,而是我们的某些自以为是的领导的问题。程序员都是在领导的指示下工作的,林彪的兵和卫立煌的兵都是农民,是一样的。
发表于 2006-5-24 08:45:49 | 显示全部楼层
你混淆了code page identifier和 System Locale两个不同的概念...

在windows 2k/xp里,有code page identifier但是无system locale的远远不止gb18030一个. 就windows 2k来说,支持的code page identifier有
950
949
936
932
875
874
870
869
866
865
864
863
862
861
860
858
857
855
852
850
775
737
720
708
500
437
28605
28599
28598
28597
28596
28595
28594
28593
28592
28591
21866
21027
21025
20949
20936
20932
20924
20905
20880
20871
20866
20838
20833
20424
20423
20420
20297
20290
20285
20284
20280
20278
20277
20273
20269
20261
20127
20108
20107
20106
20105
20005
20004
20003
20002
20001
20000
1361
1258
1257
1256
1255
1254
1253
1252
1251
1250
1149
1148
1147
1146
1145
1144
1143
1142
1141
1140
1047
1026
10082
10081
10079
10029
10021
10017
10010
10008
10007
10006
10005
10004
10003
10002
10001
10000
可是同时拥有System Locale的有几个?

gb18030为了保持同gb2312和gbk兼容,采用四字节编码来容纳unicode的所有字符,这种做法无可厚非.它为用户提供了utf-8以外另外一种选择.对中国大陆多数用户来说,选择gb18030的编码,比选择utf-8编码要容易得多,因为不存在兼容性的问题. windows 2k/xp不支持gb18030的四字节汉字的直接显示,并不代表gb18030就没有人用.比如 现在支持gb18030字符集的打印机都能够直接打印其四字节的汉字,而主机里的unicode编码汉字与外部设备的gb18030编码的转换工作,就是靠54936来进行的.

看看microsoft自己是如何解释gb18030的:
---------------------------

New Chinese Encoding GB-18030
Over the last few months, I have received many many questions about the new Chinese character encoding schema GB 18030 and how Microsoft products will support this new encoding. With the help of many colleagues, I now have some answers for you, including a link to the new GB 18030 support package.

What is GB18030?

GB18030–2000 is a new Chinese character encoding standard. The standard contains many characters and has some tough new conformance requirements. GB18030-2000 encodes characters in sequences of one, two, or four bytes. These sequences are defined as follows:

1.
       

Single-byte: 00-0x7f

2.
       

Two-byte: 0x81-0xfe + 0x40-0x7e, 0x80-0xfe

3.
       

Four-byte: 0x81-0xfe + 0x30-0x39 + 0x81-0xfe + 0x30-0x39

The single-byte section applies the standard GB 11383 coding structure and principles by using the code points 0x00 through 0x7f. GB 11383 is identical to ISO 4873:1986

The two-byte section uses two eight-bit sequences -- much in the same manner as most DBCS (double-byte character sets) do -- to express a character. The leading byte code points range from 0x81 through 0xfe. The trailing byte code points ranges from 0x40 through 0x7e and 0x80 through 0xfe. This section has the same problem as most DBCS in as much as some code points can be either a leading or trailing byte, thus making character delimitation more complicated.

The four-byte section uses the code points 0x30 through 0x39 as a way to extend the two-byte encodings. Which means the four-byte code points range from 0x81308130 through 0xfe39fe39.

Why is GB18030 unusual?

GB18030 is noteworthy in several ways:

1.
       

It is very large – with room for 1.6 million characters. This is larger than any other code page Windows supports, including Unicode.

2.
       

GB18030 characters can be one, two, or four bytes. Windows has never supported a four byte code page before and many system interfaces and data structures will not work with four byte characters. Moreover, it is impossible to tell from a particular byte whether it is the first, second, third or fourth byte of a character – this makes processing more difficult than for other code pages.

3.
       

Products sold in China must conform to this standard. The government defines and determines conformance.

4.
       

GB18030 conformance includes requirements to support some previously unsupported languages, for example Tibetan, Mongolian, Yi, and Uyghur.

Why is GB18030 important?

It is now illegal to sell products in China that do not conform to the standard.

Will GB18030 have a code page identifier?

Yes, the Microsoft code page identifier is 54936.

Will GB18030 have a System Locale?

No, it only has a code page identifier, as mentioned previously, to allow for conversions to and from Unicode.

Will GB18030 have Command Shell support?

No, it is not supported in text mode I/O. Only applications performing windowed mode I/O can use this encoding.

What are the new APIs for GB18030?

The Microsoft 4–byte Character Set Encoding Support Package (MS4BSP) provides six functions that support multiple byte encodings that can be up to four bytes long. The API set is drawn from the set of WCHAR (Unicode) functions provided by Windows 95/98/Me. In each case, the function name is identical to the ANSI and WCHAR function except with an 'L' suffix instead of 'A' or 'W'.
•       

ExtTextOutL
•       

GetTextExtentExPointL
•       

GetTextExtentPoint32L
•       

MessageBoxL
•       

MessageBoxExL
•       

TextOutL

The function parameters are identical to the 'A' version of the interface. The package is designed to expedite conversion of a code page 936 based application to GB18030 or other 4–byte encoding.

The Windows XP and Windows 2000 implementation of MS4BSP is delivered as a single dll, ms4bsp.dll. Each function invokes the MultiByteToWideChar function to convert any multibyte string inputs to UTF–16. It then invokes the 'W' version of the function and returns the output parameters that function. The dll assumes the fonts, IMEs and registry settings for the encoding are present on the system.

BOOL ExtTextOutL(
HDC         hdc,        // handle to DC
int         X,          // x-coordinate of reference point
int         Y,          // y-coordinate of reference point
UINT        fuOptions,  // text-output options
CONST RECT* lprc,       // optional dimensions
LPCSTR      lpString,   // string
UINT        cbCount,    // number of characters in string
CONST INT*  lpDx        // array of spacing values
);

BOOL GetTextExtentExPointL(
HDC         hdc,        // handle to DC
LPCSTR      lpszStr,    // character string
int         cchString,  // number of characters
int         nMaxExtent, // maximum width of formatted string
LPINT       lpnFit,     // maximum number of characters
LPINT       alpDx,      // array of partial string widths
LPSIZE      lpSize      // string dimensions
);

BOOL GetTextExtentPoint32L(
HDC         hdc,        // handle to DC
LPCSTR      lpString,   // text string
int         cbString,   // characters in string
LPSIZE      lpSize      // string size
);

Int MessageBoxL(
HWND        hWnd,       // handle to owner window
LPCSTR      lpText,     // text in message box
LPCSTR      lpCaption,  // message box title
UINT        uType       // message box style
);

Int MessageBoxExL(
HWND        hWnd,       // handle to owner window
LPCSTR      lpText,     // text in message box
LPCSTR      lpCaption,  // message box title
UINT        uType,      // message box style
WORD        wLanguageId // language identifier
);

BOOL TextOutL(
HDC         hdc,        // handle to DC
int         nXStart,    // x-coordinate of starting position
int         nYStart,    // y-coordinate of starting position
LPCSTR      lpString,   // character string
int         cbString    // number of characters
);

How does Unicode handle the four-byte sequence conversion in GB18030?

Unicode is capable of addressing more than 1.1 million code points, and the standard has provisions for 8-bit, 16-bit and 32-bit encoding forms. The 16-bit encoding is used as its default encoding and allows for its million plus code points to be distributed across 17 "planes" with each plane addressing over 65,000 characters each.

The characters in Plane 0 -- or as it is commonly called the "Basic Multilingual Plane" (BMP) -- are used to represent most of the world's written scripts, characters used in publishing, mathematical and technical symbols, geometric shapes, basic dingbats (including all level-100 Zapf Dingbats), and punctuation marks.

But in addition to the support for characters in modern languages and for the symbols and shapes just mentioned, Unicode also offers coverage for other characters, such as less commonly used Chinese, Japanese, and Korean (CJK) ideographs, Arabic presentation forms, and musical symbols. Many of these additional characters are mapped beyond the original plane using an extension mechanism called "surrogate pairs." It is these surrogate pairs that allow the mapping of the the GB18030 4-byte sequences to Unicode.


原帖由 韦剑 于 2006-5-23 16:55 发表
  GB18030,想说爱你不容易


  之所以会有此感叹,并非觉得GB18030的编码框架有什么不妥,而是对该标准在实际应用中遇到的尴尬情形的一些个人看法。

  疑惑一:GB18030到底是一种ANSI编码还是Unicod ...

[ 本帖最后由 fromnuaa 于 2006-5-24 08:48 编辑 ]
发表于 2006-5-24 08:55:04 | 显示全部楼层
当然可以出现ext a或者ext b的汉字,用unicode编码最直接;用gb18030编码需要作一下转码. 只有gb18030-2005才支持ext b的文字.

原帖由 extc 于 2006-5-24 01:07 发表
那就是说现在在VB, VC++ 这类程序是不可能出现CJK ExtA 或者CJK ExtB 字符吧?

[ 本帖最后由 fromnuaa 于 2006-5-24 09:00 编辑 ]
 楼主| 发表于 2006-5-24 08:55:15 | 显示全部楼层
写程序的时候用GBK和UNICODE,将码位转换器加进去,就声称自己支持了。这个年头,程序员说的话算数。对我们普通用户来说,使用你的软件,能看得见汉字就行了。

盛版主说得就是现在的实情。人是很现实的,既然普通开发人员无法像政府或OS厂商那样执掌乾坤,那么最实际的做法就是像微软敷衍我们那样暗渡陈仓了。写这篇文章的目的并不是真想为GB18030争取到一个应用上真正可行的方案,因为就像我最后所说:这不是我们这些小人物可以改变得了的。只是既然已经“发现”了这其中的“猫腻”,不说出来总有些如梗在喉的感觉……怎么说呢,至少算是为新上手开发文本处理软件的兄弟们留下一些小提示吧。
发表于 2006-5-26 12:34:30 | 显示全部楼层
希望多见到一些这样的纯技术文章
 楼主| 发表于 2006-5-26 13:01:56 | 显示全部楼层

答fromnuaa朋友

你混淆了code page identifier和 System Locale两个不同的概念...

在windows 2k/xp里,有code page identifier但是无system locale的远远不止gb18030一个. 就windows 2k来说,支持的code page identifier有
950
949
936

谢谢你的提醒,不过根据我对Win32API的研究,就文本处理而言,系统本地标识符的作用根本不能和系统代码页相提并论。因为在实际的处理中,系统是根据代码页属性来决定要送去显示在软件界面上的字符串是否包含非法字符的,而系统本地标识符只是表示这个系统原来是在哪个国家或地区发行使用的一个区域性标志罢了。

举个最简单的例子,我自己现在用的是简体中文版的XP,如果我把代码页设为CP950的话,系统就会按BIG5编码而不是GBK来解释所有ANSI程序里面的文本。虽然系统的本地标识符并没有变,还是0x0804(中国)。但这个0x0804的本地标识符并不能阻止系统按照当前代码页(CP950)来处理ANSI文本数据。这足以说明系统本地标识符对于ANSI(本地编码字符集)文本的识别和处理是没有作用的,起作用的是代码页。
发表于 2006-5-26 15:50:43 | 显示全部楼层
呵呵,你又混淆了两个不同的概念了:input locale 和 system locale了.

你说的0804指的是input locale,不是system locale.

microsoft 对system locale的解释是:

The system locale is not really a locale. It determines which codepages (ANSI, DOS, and Macintosh) are used on the system by efault. Changing the system locale also installs the necessary bitmap font files to support legacy applications in the language you selected.

As the name suggest, it's a per system setting. It requires a reboot to change. You can only select a system locale, if the appropriate language group is installed, i.e., you need the script support to select a system locale.

Some times there is no noticeable difference between two system locales.For example, there is no difference between the German Standard and German - Austria system locale. In general system locales of one language group are very similar and might be only different in the OEM or MAC codepage.

If it weren't be so long the system locale should be called legacy applications compatibility setting, because that is really what it is. Setting the system locale to a certain language instructs Windows 2000 to emulate a legacy operating system (DOS, Windows 3.1, and Windows 9x) localized to this language. Only applications, which are not fully Unicode, are affected by this setting.

An ANSI application should check the system locale at least during installation.

Example: 1 - A German user wants to run a Japanese application, which was designed for Japanese Windows 95. The user has to select Japanese as system locale to do this . Note: German legacy applications will not run flawlessly anymore. German umlauts will not be displayed correctly.

2 - The same German user wants to type Japanese text in a German legacy applications. The user has also to select Japanese as a system locale. Note: This will limit his ability to enter German text in legacy applications. German umlauts will not be displayed correctly.

3 - An Arabic user wants to type Arabic, French, and English in an Arabic legacy applications. The user has to select Arabic as a system locale. The Arabic ANSI codepage contains most of the characters used for French and all of the English characters.
=======

自win2k问世以来,它的多语言支持变得异常复杂,分为多个不同的层面,有内核、界面、输入法、字符集、字库甚至日期、货币表示等等,也就有了多个不同的locale,有System Locale、User Locale、Thread Locale、Input Locale等等。回到54936来说,windows把它当作一个只是用来转码的codepage,不支持直接显示和输入。这样的codepage在windows里很多,比如印度文的5700x、台湾几种中文编码的2000x等等,它们跟gb18030一样,只能用作转码,不能直接显示和输入。

windows不支持gb18030的直接显示和输入,并非技术上不可行,而是不屑于实现,unicode才是它今后的发展方向。

原帖由 韦剑 于 2006-5-26 13:01 发表

谢谢你的提醒,不过根据我对Win32API的研究,就文本处理而言,系统本地标识符的作用根本不能和系统代码页相提并论。因为在实际的处理中,系统是根据代码页属性来决定要送去显示在软件界面上的字符串是否包含非法 ...
 楼主| 发表于 2006-5-26 16:53:35 | 显示全部楼层
呵呵,你又混淆了两个不同的概念了:input locale 和 system locale了.

你说的0804指的是input locale,不是system locale.

microsoft 对system locale的解释是:

既然你认为有input locale 和 system locale之分,那么请指教:对于简体中文系统,input locale 和 system locale分别是多少?用GetSystemDefaultLCID 函数得到的是input locale 还是system locale?看资料、找资料谁都会,但实验结果要靠实际做出来的。

另外还想请你注意,要说就说你自己的意见。不用贴一大堆Win32开发手册或MSDN上的资料过来。那些东西我知道在哪里,至于怎么理解,大家意见或有不同,你只需把你自己的想法说出来一起讨论就行了。不用拿你自己来代表它们,你只能代表你自己。
发表于 2006-5-26 19:20:25 | 显示全部楼层
GB18030其实是“政治上正确”的产物,与国际接轨,不要标新立异!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大中文系 ( 京ICP备12040209号

GMT+8, 2017-5-28 12:46 , Processed in 0.125064 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表