java转gb18030抛异常,这个'?'字的转换为什么是这个结果(GBK和GB18030互转)

这个问题基本弄清楚了,解释如下:

首先说字符集,GBK字符集有80个字符是后来增补的,因为需要与GB18030兼容,所以放在GB18030的PUA区(此时这80个字符也在Unicode中有自己的对应的一套编码了,这一套编码在GB18030和GBK中的映射是一致的),后来这80个字符被Unicode字符集收录,于是在Unicode中有了自己的第二套编码,但是这第二套编码是不被GBK所兼容,仅GB18030可识别,这些字符的新编码也叫非PUA编码。

简单说,这几个字符从GBK到Unicode,对应编码为A,从GB18030到Unicode,对应编码为A和A',Oracle在转换时选择的就是转为A',A'是转不回GBK编码的。这就是第一个'?出现'的原因。

做一个实验可验证:

select convert('?','ZHS16GBK','ZHS32GB18030')  A,

convert(convert('?','UTF8','ZHS32GB18030'),'ZHS16GBK','UTF8') A1,

dump(convert('?','UTF8','ZHS32GB18030')) A2

from dual;

A  A1 A2

-- -- ------------------------

? ? Typ=1 Len=3: 228,182,174

'?'字的Unicode的非PUA编码是4DAE,换算成UTF8的编码方式是11100100 10110110 10101110,刚好是228,182,174

而且从转换结果看,我们有理由相信Oracle在进行convert时是把源字符集的字符先转换到Unicode字符集,然后再转换到目标字符集。

再做另一个实验:

select

dump(convert('?','ZHS32GB18030','ZHS16GBK')) B,

dump(convert(convert('?','UTF8','ZHS16GBK'),'ZHS32GB18030','UTF8') )B1,

dump(convert('?','UTF8','ZHS16GBK')) B3

from dual;

B                                              B1                                           B3

--------------------------               --------------------------               ------------------------

Typ=1 Len=4: 131,54,207,57 Typ=1 Len=4: 131,54,207,57 Typ=1 Len=3: 238,161,163

确实B和B1两种转换结果相同。另外对原贴中的'??'的解释,我们从B3的结果看,从GBK转换到UTF8时,转换后的UTF8编码对应的Unicode编码为E863,转换结果是正确的。而从E863转换到GB18030时结果是131,54,207,57,这个换算后对应的编码是8336 CF39,对应不到任何GB18030的字符,所以显示'??',但具体131,54,207,57是如何产生的,我还没有确切弄明白,可能是Oracle的BUG,也可能是对PUA区选择的问题。

以下是那80个字以及对应的GBK编码(GB18030编码也相同),PUA编码和非PUA编码(这两个是Unicode编码)

汉字        GBK编码        PUA编码        非PUA编码

?        FE50        E815        2E81

?        FE51        E816        20087

?        FE52        E817        20089

?        FE53        E818        200CC

?        FE54        E819        2E84

?        FE55        E81A        3473

?        FE56        E81B        3447

?        FE57        E81C        2E88

?        FE58        E81D        2E8B

?        FE59        E81E        9FB4

?        FE5A        E81F        359E

?        FE5B        E820        361A

?        FE5C        E821        360E

?        FE5D        E822        2E8C

?        FE5E        E823        2E97

?        FE5F        E824        396E

?        FE60        E825        3918

?        FE61        E826        9FB5

?        FE62        E827        39CF

?        FE63        E828        39DF

?        FE64        E829        3A73

?        FE65        E82A        39D0

?        FE66        E82B        9FB6

?        FE67        E82C        9FB7

?        FE68        E82D        3B4E

?        FE69        E82E        3C6E

?        FE6A        E82F        3CE0

?        FE6B        E830        2EA7

?        FE6C        E831        215D7

?        FE6D        E832        9FB8

?        FE6E        E833        2EAA

?        FE6F        E834        4056

?        FE70        E835        415F

?        FE71        E836        2EAE

?        FE72        E837        4337

?        FE73        E838        2EB3

?        FE74        E839        2EB6

?        FE75        E83A        2EB7

?        FE76        E83B        2298F

?        FE77        E83C        43B1

?        FE78        E83D        43AC

?        FE79        E83E        2EBB

?        FE7A        E83F        43DD

?        FE7B        E840        44D6

?        FE7C        E841        4661

?        FE7D        E842        464C

?        FE7E        E843        9FB9

?        FE80        E844        4723

?        FE81        E845        4729

?        FE82        E846        477C

?        FE83        E847        478D

?        FE84        E848        2ECA

?        FE85        E849        4947

?        FE86        E84A        497A

?        FE87        E84B        497D

?        FE88        E84C        4982

?        FE89        E84D        4983

?        FE8A        E84E        4985

?        FE8B        E84F        4986

?        FE8C        E850        499F

?        FE8D        E851        499B

?        FE8E        E852        49B7

?        FE8F        E853        49B6

?        FE90        E854        9FBA

?        FE91        E855        241FE

?        FE92        E856        4CA3

?        FE93        E857        4C9F

?        FE94        E858        4CA0

?        FE95        E859        4CA1

?        FE96        E85A        4C77

?        FE97        E85B        4CA2

?        FE98        E85C        4D13

?        FE99        E85D        4D14

?        FE9A        E85E        4D15

?        FE9B        E85F        4D16

?        FE9C        E860        4D17

?        FE9D        E861        4D18

?        FE9E        E862        4D19

?        FE9F        E863        4DAE

?        FEA0        E864        9FBB

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值