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

news2024/11/16 11:55:17

背景

最近在做一个去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 AS
  2  (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 T
  6  UNION ALL
  7  SELECT 'ZHS32GB18030',UTL_I18N.STRING_TO_RAW(U4DAE,'ZHS32GB18030'),
  8  UTL_I18N.STRING_TO_RAW(UE863,'ZHS32GB18030') FROM T
  9  UNION ALL
 10  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    FE9F

SQL>

这里注意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.coloradmin.cn/o/1377758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue.js设计与实现阅读-2

Vue.js设计与实现阅读-2 1、前言2、框架设计的核心要素2、1 提升用户体验2、2 控制代码体积2、3 Tree-Shaking2、4 特性开关2、5 错误处理 1、前言 上一篇我们了解到了 命令式和声明式的区别,前者关注过程,后者关注结果了解了虚拟dom存在的意义&#x…

Excel地址

解题思路: 根据题中歪歪和笨笨的话可以有两种解法。 1.输入的数为多大,则循环1多少次,当值为27时就要进行进位操作。这时要分情况讨论。 当集合中元素为一个时,如26,则需要变为1 1,集合元素个数加一。 当…

C语言指针(一)

目录 1.什么是指针 2.指针变量和地址 1.解引用操作符 2.指针变量类型的意义 3.void*指针 4.const修饰指针 1.const放在*左边 2.const放在*右边 3.指针的运算 1.指针加减整数 2.指针减指针 3.指针比较大小 4.野指针 1.没有给指针变量初始化 2.指针指向的空间释放 …

MES系统中的设备管理及设备数据采集

随时工厂数字化建设的大力推进,设备管理的效率得到了很大的提升,特别是作为机加工企业,设备是整个企业非常重要的核心资产。 一、设备进行数据采集面临痛点: 设备数据状况无法获取与掌握 设备老旧,信息化基础差&…

制造知识普及--MES系统中的调度排产管理

要想弄清楚MES系统调度排产的管理机制,则要首先搞清楚车间调度排产是一套怎样的工作流程,它的难点在什么地方? 生产调度指的是具体组织实现生产作业计划的工作,是对执行生产作业计划过程中发生的问题和可能出现的问题&#xff0c…

Springboot+vue学生考试系统

Springbootvue学生考试系统 演示视频 【Springbootvue学生考试系统】 https://www.bilibili.com/video/BV1gk4y1Q7em/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 主要功能: 管理员可以添加题库分配课程教师,指定考试范围指定…

性能测试分析案例-定位服务吞吐量下降

环境准备 预先安装 docker、curl、wrk、perf、FlameGraph 等工具 sudo yum groupinstall Development Tools # 安装火焰图工具 git clone https://github.com/brendangregg/FlameGraph # 安装wrk git clone https://github.com/wg/wrk cd wrk && make && sud…

LeetCode 38 外观数列

题目描述 外观数列 给定一个正整数 n ,输出外观数列的第 n 项。 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列: countAndSay(1) "1…

数字信号处理 唐向宏著 pdf +课后答案 免费下载

数字信号处理——原理、实现与仿真 pdf 唐向宏著 +课后答案 杭州电子科技大学 费劲心思在网上花钱买的,共享给大家 永久链接:https://wwi.lanzoup.com/b0140pf4f 密码:aflj 里面除了有原书PDF,还有课后题答案

二极管选型怎么选?常用参数要熟练~

同学们大家好,今天我们继续学习杨欣的《电子设计从零开始》,这本书从基本原理出发,知识点遍及无线电通讯、仪器设计、三极管电路、集成电路、传感器、数字电路基础、单片机及应用实例,可以说是全面系统地介绍了电子设计所需的知识…

AnyText多语言文字生成与编辑模型——让AI绘图自由添加精美文字

随着AIGC的爆火,图片生成技术得到飞速发展,当前AI生成的图片已达到真假难辨的高保真度。例如stable diffusion与midjourney为代表的文生图大模型。不过,当合成图片中出现文字内容时,现存的AI技术依然无法驾驭文字内容。因此,modescope提出了一种新型的文字生成方法,此方法…

数谷·企声|贵州空港智能科技:以“智”提“质”,助力贵阳智慧机场建设

当前,我国民航正大力推进“平安、绿色、智慧、人文”的四型机场建设。贵州空港智能科技有限公司(下称“空港智能科技”)作为贵州民航产业集团有限公司(下称“民航产业集团”)信息化建设的排头兵和主力军,近…

SQL-条件查询与聚合函数的使用

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL 🍹文章作者技术和水平很有限,如果文中出现错误&am…

(leetcode)Z字形变换 -- 模拟算法

个人主页:Lei宝啊 愿所有美好如期而遇 题目链接 . - 力扣(LeetCode) 输入描述 string convert(string s, int numRows),输入一个字符串s,以及一个行数numRows,将字符串按照这个行数进行Z字形排列&…

FPGA UDP协议栈:基于88E1111,支持RGMII、GMII、SGMII三种模式,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的以太网方案本协议栈的 1G-UDP版本本协议栈的 10G-UDP版本本协议栈的 25G-UDP版本1G 千兆网 TCP-->服务器 方案1G 千兆网 TCP-->客户端 方案10G 万兆网 TCP-->服务器客户端 方案 3、该UDP协议栈性能4、详细设计方案设…

C练习——魔术师猜三位数

题目: 有一种室内互动游戏,魔术师要每位观众心里想一个三位数abc(a、b、c分别是百位、十位和个位数字),然后魔术师让观众心中记下acb、bac、bca、cab、cba五个数以及这5个数的和值。只要观众说出这个和是多少&#xf…

使用Python进行客户行为分析

客户行为分析是一个有价值的过程,它使企业能够做出数据驱动的决策,增强客户体验,并在动态市场中保持竞争力。 下面是我们可以遵循的客户行为分析任务的过程: 收集与客户互动相关的数据。它可以包括购买历史记录,网站…

C桑(Cython)从入门到入土(2): np数组操作对比

C桑(Cython)从入门到入土 2. np数组操作对比 Node sc518 Copy has image data of type unsigned long long实际上, 👆🏻这个错误是我探索Cython的缘起… code1: Form: 更现代的方法是使用内存视图而不是指针: cdef np.uint32_t[:,:,::1] …

爬虫逆向破解翻译接口参数

Python 请求baidu翻译接口:https://fanyi.baidu.com/v2transapi?fromzh&toen 步骤一: 查找构建请求参数 JS 断点发现如下参数: w {from: _.fromLang,to: _.toLang,query: e,transtype: i,simple_means_flag: 3,sign: b(e),token: windo…

【Linux】宝塔端口不通

1.问题描述:端口不通 以端口16588为例: 服务器16588端口是关闭的,防火墙规则是放通的,是由于服务器内的对应程序没有监听到 对应 的公网上 图1:端口检测 图2: 端口已放行 此时访问仍然不通,但…