恼人的“龙天“(䶮)--谈谈从GBK转到GB18030的特殊情况

背景

最近在做一个去O迁移适配,刚好也有友商在一起做,两边测试方式不一样。友商先遇到了一个问题,就是在ORACLE中某个的2字节GBK字符到迁移到友商的库中变成了4字节,刚好那个字段在这个字是2字节的时候,已经存满了,转换成4字节后就会超长,死活都导不进去,经分析,是因为友商建库时选择了GB18030字符集,可是为什么2字节的GBK字符到了GB18030会变成4字节?而我在MogDB中建GBK的库,这个字能正常导入,不会超长。
这个字有何神奇之处?
在经过一些调查及测试验证后,特整理此文。

分析过程

这个字的外形是 ,上面是“龙”,下面是“天”。其实正常的输入法是可以输入这个外形的字的,但是,实际上你用输入法输入的这个字,并不是我上面提到的这个字,它们只是外形完全一样的“两个字”,这里我说“两个字”是对于unicode编码而言,或者换种说法,这个外形的字,在GB(GBK/GB18030)字符集的演进历史中,曾经占据了两个unicode编码,在windows中文区域里,使用ANSI时 ,这两个unicode编码的字符都可以正常显示字形。而在流行的UTF8编码的网页上,其中一个字可能是无法正常显示的,而这个字就是数据库迁移中存在问题的字,而这个字的起源,要追述到GBK编码定义


(https://www.zhihu.com/question/403694151)
如上图 右下角的位置,GBK+FE9F 这个编码,对应的unicode编码为U+E863,然后我们去查下unicode官网,找找这个编码,

在这里插入图片描述

在unicode官网里,这个编码并没有字形对应,而且该位置属于PUA(私人编码区)。

我们再来看GB18030-2022中U+E863是什么
在这里插入图片描述

U+E863对应的GB18030编码为 GB18030+8336CF39 ,此处也没有字形。也就是说,GBK编码的FE9F这个字,既不被UNICODE承认,也不在最新的国家强制标准GB18030-2022里。

可是,不是说GB18030比GBK能支持更多的生僻字么?其实,这个字并不是没有了,而是GB18030把它"直接兼容"了。

我们直接用GBK编码的FE9F在GB18030标准里找
在这里插入图片描述

可以看到这里的确有对应的字形,而且就是“龙天”,这个字对应的UNICODE编码为U+4DAE,于是我们再去UNICODE官网找找
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

果然在这里也能找到。

我们以UNICODE编码来整理一下这两个字的各种编码(由于这个字在UTF8中没有字形对应,所以可能部分网页上会显示方框,如果复制出来放到中国区域的windows的记事本里,就可以正常显示对应的字,因为当成GBK显示了)

UNICODE4DAEE863
UTF8E4B6AEEEA1A3
GB18030FE9F8336CF39
GBKFE9F

然后我测试了,在较新版本的ORACLE中,使用UTL_I18N里的raw_to_char/string_to_raw函数,也可以得到上述相同的结果

SQL> WITH T AS2  (SELECT UTL_I18N.RAW_TO_CHAR('4DAE','AL16UTF16') U4DAE ,3  UTL_I18N.RAW_TO_CHAR('E863','AL16UTF16') UE863 FROM DUAL)4  SELECT 'AL32UTF8' encoding, UTL_I18N.STRING_TO_RAW(U4DAE,'AL32UTF8') "4DAE",5  UTL_I18N.STRING_TO_RAW(UE863,'AL32UTF8') "E863" FROM T6  UNION ALL7  SELECT 'ZHS32GB18030',UTL_I18N.STRING_TO_RAW(U4DAE,'ZHS32GB18030'),8  UTL_I18N.STRING_TO_RAW(UE863,'ZHS32GB18030') FROM T9  UNION ALL10  SELECT 'ZHS16GBK',UTL_I18N.STRING_TO_RAW(U4DAE,'ZHS16GBK'),11  UTL_I18N.STRING_TO_RAW(UE863,'ZHS16GBK') FROM T;ENCODING     4DAE    E863
------------ ------- ---------
AL32UTF8     E4B6AE  EEA1A3
ZHS32GB18030 FE9F    8336CF39
ZHS16GBK     A3BF    FE9FSQL>

这里注意ORACLE中的 U+4DAE 在ZHS16GBK其实并不是 “A3BF”,而是因为并没有对应的字符,ORACLE把它转换成了全角问号(转成什么符号与当前环境的区域语言有关)。

引发的问题

所以,这里出现一个很尴尬的情况:
在去O过程中,原本在Oracle中使用的是GBK字符集,存入了GBK字符集支持的"FE9F"这个字符,如果迁移的目标库也是使用GBK字符集,那当然皆大欢喜。可是GBK目前已被国家标准废弃,必须要使用GB18030,而编码转换软件如果按照UNICODE标准进行转换,那么这个字将被转换成GB18030的"8336CF39" ,且不说数据可能会变长导致无法存入数据库,更大的问题是,GB18030中的"8336CF39"并没有对应的字形,会导致很多软件的UI无法显示这个字!

于是对于GBK和GB18030的转换,就不应该使用UNICODE的码点对应关系来进行转换了,这对于现有的绝大多数会涉及到文本转码的软件带来灾难。现有很多开发语言的内部都是默认使用的UTF8(比如JAVA、GO),各种字符的转入转出几乎都是通过UNICODE来进行中转,遇到这种转换的场景,很有可能会出现问题。相关报道有很多,这里随便列两篇:

1.# 谈困在系统里的生僻字,如何消除数字化“盲区”?

2.# 一个名字叫“䶮”的人的苦恼:开不了银行账户,用不了微信、支付宝

处理建议

  1. 对于软件开发商,转码软件或者转码模块应该单独编写GBK到GB18030的转码规则。比如本文的例子,GBK的 “FE9F” ,就应该映射到 GB18030的 “FE9F” ,而非通过UNICODE编码进行中转得到的 “8336CF39”;或者更新GBK的映射,使其unicode码和GB18030的映射关系一致(windows就是这么处理的 : windows-936-2000)
  2. 对于对被强制执行标准的软件用户,应提前采取措施应对GBK编码转到GB18030所带来的影响(原本用UTF8转到GB18030的没有此类问题),不是所有的软件开发商都会细致地去考虑编码转换问题,GB18030强制标准只要求能支持输入输出标准里的字符,并不要求支持和其他字符集进行转换。
  3. 对于所有的新软件开发,不应再使用GBK字符集,推荐使用UTF8(或者GB18030)
  • 本文作者: DarkAthena
  • 本文链接: https://www.darkathena.top/archives/longtian-yan-encoding-gbk-gb18030
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/343119.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】使用tkinter设计开发Windows桌面程序记事本(4)

上一篇:【Python】使用tkinter设计开发Windows桌面程序记事本(3)-CSDN博客 下一篇: 作者发炎 衔接上一篇文章,本文章完成了"页面设置"子窗口的部分功能,并且点击"确定"按钮后会把当前…

使用U盘作为系统的启动盘

1.我们使用到的工具ventoy-1.0.96.rar 下载资源 https://download.csdn.net/download/u011442726/88735129 2.怎么使用 ventoy软件的使用非常简单,直接解压后,把u盘插到电脑,然后点击exe这个文件即可。 然后点击之后,直接点击安…

人工智能任务4-读懂YOLOv5模型的几个灵魂拷问问题,深度理解 YOLOv5模型架构

大家好,我是微学AI,今天给大家介绍一下人工智能任务4-读懂YOLOv5模型的几个灵魂拷问问题,深度理解 YOLOv5模型架构。YOLOv5是一种高效且精确的目标检测模型,由ultralytics团队开发。它采用了轻量级的网络结构,能够在保…

HDFS概述

文章目录 HDFS背景定义HDFS 优缺点HDFS 组成HDFS文件块大小 HDFS背景定义 背景 先给大家介绍一下什么叫HDFS,我们生活在信息爆炸的时代,随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁…

武汉灰京文化:手游市场正呈现出多元化的发展趋势

移动游戏作为近年来全球范围内备受关注的领域之一,其崛起之迅速令人瞩目。尤其值得注意的是,新兴的细分玩法以及类型多样的游戏产品的出现,已经彻底改变了人们对于移动游戏的认知。在高速增长的移动互联网浪潮推动下,多样化游戏产…

基于LVGL编写的windows串口工具: LCOM

LCOM: Serial Port Tools based on LVGL (PC Software) 一直以来我都想用LVGL做一个真正意义上的PC软件,来验证或者表达LVGL出色的特性,现在我用LCOM做到了! LCOM 是一个基于LVGL编写的串口工具,界面简洁,功能出色&a…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题一 理论题

竞赛需要完成三个阶段的任务,分别完成三个模块,总分共计 1000分。三个模块内容和分值分别是: 1.第一阶段:模块一 网络平台搭建与设备安全防护(180 分钟,300 分)。 2.第二阶段:模块二…

iOS xcode 15.1 打包报错

真机调试的时候没问题,打包的时候报错了 #报错 解决办法 pods.xcodeproj - build phases - compile sources - compiler flags pods.xcodeproj - Targets-support files pods-xx-frameworks

国内镜像源配置方法(包括临时和永久方法)

国内镜像源: 阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/豆瓣 http://pypi.douban.com/simplePython官方 https://pypi.python.org/simple/v2ex http://pypi.v2ex.com/simple/中国科学院 http://pypi.mi…

sectigo通配符dv证书400元买一年送1月实际签发13个月

Sectigo就是众多颁发数字证书的CA认证机构之一,旗下的DV通配符SSL证书作为一种加密通信工具,广泛应用于保护网站数据的安全。其中,SectigoDV通配符SSL证书是一种受欢迎的产品,它不仅能够提供强大的加密功能,还可以提高…

SpringBoot 引入分页插件 PageHelper

官网 https://pagehelper.github.io/docs/howtouse/ 引入步骤 第1步&#xff1a;引入依赖 <!--分页插件--> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.2</vers…

【Git】查看凭据管理器的账号信息,并删除账号,解决首次认证登录失败后无法重新登录的问题

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是是《代码管理工具》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的…