GBK编码字符集中有80个汉字在unicode未定义此80个汉字字符时,使用了unicode的PUA区域的代码点。后来unicode正式定义了此80个汉字字符,使用了新的代码点来表示。这样就出现有80个汉字在unicode定义的代码点区域中有两个不同的代码点。

例如,GBK编码字符“䶮”在unicode有两个不同点的代码点,分别是PUA中的0xE863,非PUA区的0x4DAE。这两个代码点对应同一字符,在字形方面天字的第一笔有差异。

   此字的含义如下:

(龑) 拼音: yǎn 笔划: 9
部首: 龙
QQ五笔输入法:DXGD 拼音输入法输入:yan
百度输入法(拼音):yan
出处:五代时南汉刘岩,为自己名字造的字。
乃采《周易》“飞龙在天”之义为“?”字,音“俨”,以名焉
上龙下天。意思即为:①飞龙在天。②喻权势。③坚强。④有我无敌,唯吾独尊。等等

    windows客户端通过输入法输入时此字符的代码点为0xE863,在aix服务上使用jre1.4.2把字符串转码为GBK编码字节数组时,此字符对应的字节为0x3f。这样就出现了乱码问题。

    下面是我们分别在windows sunjre1.4.2与aix上ibm jre1.4.2上测试的情况。

  • windows上测试的日志输出

0xe863字符:
用字符编码集[gb2312]表示unicode[0xe863]的值为:[3f]
用字符编码集[gbk]表示unicode[0xe863]的值为:[fe9f]
用字符编码集[gb18030]表示unicode[0xe863]的值为:[8336cf39]
0x4DAE字符:
用字符编码集[gb2312]表示unicode[0x4dae]的值为:[3f]
用字符编码集[gbk]表示unicode[0x4dae]的值为:[3f]
用字符编码集[gb18030]表示unicode[0x4dae]的值为:[fe9f]
  • aix上测试的日志输出

0xe863字符:
用字符编码集[gb2312]表示unicode[0xe863]的值为:[3f]
用字符编码集[gbk]表示unicode[0xe863]的值为:[3f]
用字符编码集[gb18030]表示unicode[0xe863]的值为:[8336cf39]
0x4DAE字符:
用字符编码集[gb2312]表示unicode[0x4dae]的值为:[3f]
用字符编码集[gbk]表示unicode[0x4dae]的值为:[fe9f]
用字符编码集[gb18030]表示unicode[0x4dae]的值为:[fe9f]

    从上面的日志可以看出,两种jre的处理细节上的差异。从测试日志也可以看出,如果使用GB18030编码字符集,则两种jre处理的结果是一致。可以采用GB18030来规避此乱码问题。

    不过,在需要支持不同国家或语言的字符传输或存储时,使用UTF-8编码等才是正道。