GB2312,GBK,Unicode

【计算机学习笔记】GB2312、Unicode等字符编码以及宽窄字符的理解 之前编写win32程序时没怎么关注过宽字符到底是个啥东西,最近在编写网络框架又遇到字符相关的问题,所以写一篇文章记录一下(有些部分属于个人理解,如果有错误欢迎指出) 阅读详情

 

           为了使我们的计算机能够显示文字或字符,首先要内存中可以存储文字或字符。要存储一个文字或者字符有多种方式:

           (1)我们可以把文字变为图片(点阵),直接保存起来,当需要显示的时候,把图片绘制出来。

           (2)把文字或者字符变成矢量数据存储起来,需要显示的时候,再根据矢量规则绘制出来即可。

           (3)把文字或者或者先编号,然后要问题显示样式与编号一一对应起来,当需要显示文字的时候,首先根据编号去找文字对应的图片,然后绘制。

 

          仔细分析以上三种方式,第一种和第二种理论上都是可行的。但是第一种直接存储图片数据量会很大,第二种虽然基本上能够解决第一种情况的问题,但是和第一种一样还存在一个很严重的问题,就是各个不同厂商的的文字或者字符不能够通用,并且换一台计算机,则他不知道绘制规则。第三种就是计算机文字编码的方式了。

          具体做法是:首先把我所想用到的文字都变成一个唯一编码,这个编号发布出去,让所有人都知道,这个编号就称之为文字编码,每个文字对应唯一编码,当计算机绘制文字的时候先根据这个编码去找对应的字体文件中这个编码的图片或者矢量图形来绘制即可。只要大家都遵循这个编码规范,不同的字体就可以使用在不同计算机不同硬件了。

 

         常见的编码有ASCII、GB2312、GBK、Unicode等。这里的重点是GBK和Unicode。

        GB2312码是中华人民共和国国家汉字信息交换用的编码,全称《信息交换用汉字编码字符集——基本集》,是国家标准总局1981年发布。整个字符集分为94个区,每个区有94个位,每个区位上一个字符。区码转成16进制加上2020H转成国际码,国际码加上8080H就可以转成机内码。为了使汉字的编码不重复,每个汉字使用两个字节来表示,高位一个字节对应着区码,低位字节对应着位码,区码和位码构成一个汉字。在GB2312的94个区中,01-09区是特殊字符,16-55区是一级汉字,按照拼音进行排序,56-87区是二级汉字,按照偏旁排序。

        GBK,全称《汉字内码扩展规范》,是由全国信息技术标准化技术委员会制定。GBK编码向下与GB2312编码完全兼容。GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

        Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

        如下两张图片就可以反映出来GBK编码方式以及GBK和GB2312的关系,图片来自维基百科。

        

 

             在项目中为了可以将文字编码转换成开发环境和语言支持的格式,必须要写GBK和Unicode的编码转换。简单的来说,开发的时候就是给你一个文字,但是你的平台接口是Unicode编码,而你得到的是GBK编码,所以必须进行转换,转换需要一个映射关系,即GBK编码代表的字符,所对应的Unicode编码。

        

             为了获取到GBK编码和Unicode编码之间的对应关系,下面是我写的C#代码。

 

        /// <summary>
        /// 从区位码获取GBK编码
        /// </summary>
        /// <param name="quCode"></param>
        /// <param name="weiCode"></param>
        /// <returns></returns>
        public int QuWeiCode2GBK(int quCode, int weiCode)
        {
            quCode += 0xa0;
            weiCode += 0xa0;

            byte[] bytes = new byte[2];
            bytes[1] = (byte)quCode;
            bytes[0] = (byte)weiCode;
            ushort snum = BitConverter.ToUInt16(bytes, 0);
            return (int)snum;
        }

        /// <summary>
        ///  从GB编码转换到Unicode编码
        /// </summary>
        /// <param name="gbCode"></param>
        /// <returns></returns>
        public int GBK2Unicode(int gbCode)
        {
            byte[] bytes = BitConverter.GetBytes(unchecked((ushort)gbCode));
            Array.Reverse(bytes);
            string word = Encoding.GetEncoding("GBK").GetString(bytes);
            byte[] bs = Encoding.Unicode.GetBytes(word);
            ushort snum = BitConverter.ToUInt16(bs, 0);
            return (int)snum;
        }

        /// <summary>
        /// 从Unicode编码获取BKB编码
        /// </summary>
        /// <param name="uniCode"></param>
        /// <returns></returns>
        public int Unicode2GBK(int uniCode)
        {
            byte[] unCode = BitConverter.GetBytes(unchecked((ushort)uniCode));
            string word = Encoding.Unicode.GetString(unCode);
            byte[] gbCode = Encoding.GetEncoding("GBK").GetBytes(word);
            Array.Reverse(gbCode);
            ushort snum = 0;
            if (gbCode.Length > 1)
                snum = BitConverter.ToUInt16(gbCode, 0);
            if (gbCode.Length == 1)
                snum = (unchecked((ushort)(gbCode[0])));
            return (int)snum;
        }

        /// <summary>
        /// 获取GB2312的所有字符编码
        /// </summary>
        /// <returns></returns>
        public int[] GetBasicCode()
        {
            List<int> gbBasicCode = new List<int>();
            int quCode = 0;
            int weiCode = 0;
            for (int i = 1; i < 100; i++)
            {
                if (i <= 9 || (i >= 16 && i <= 87))
                    quCode = i;
                for (int j = 1; j <= 94; j++)
                {
                    weiCode = j;
                    gbBasicCode.Add(QuWeiCode2GBK(quCode, weiCode));
                }
            }
            return gbBasicCode.ToArray();
        }

        /// <summary>
        /// 获取GBK扩展包3的编码
        /// </summary>
        /// <returns></returns>
        public int[] GetGBK3Code()
        {
            List<int> indexs = new List<int>();
            for (int i = 0x8140; i < 0xa0ff; i++)
            {
                if ((i & 0x000000ff) != 0x7f && (i & 0x000000ff) >= 0x40 && (i & 0x000000ff) < 0xff)
                    indexs.Add(i);
            }
            return indexs.ToArray();
        }

        /// <summary>
        /// 获取GBK 3扩展包的编码和GB2312编码,并按照升序排列
        /// </summary>
        /// <returns></returns>
        public List<int> GetUsedGBKCode()
        {
            int[] basicCodes = GetBasicCode();
            int[] gbk3Codes = GetGBK3Code();
            int[] indexs = new int[basicCodes.Length + gbk3Codes.Length];
            Array.Copy(basicCodes, 0, indexs, 0, basicCodes.Length);
            Array.Copy(gbk3Codes, 0, indexs, basicCodes.Length, gbk3Codes.Length);
            Array.Sort(indexs);

            List<int> delIndexs = new List<int>();
            for (int i = 0; i < indexs.Length; i++)
            {
                int code1 = GBK2Unicode(indexs[i]);
                int code2 = Unicode2GBK(code1);
                if (code2 != indexs[i])
                    delIndexs.Add(i);
            }

            List<int> trIndexs = new List<int>();
            int loop = 0;
            for (int i = 0; i < indexs.Length; i++)
            {
                if (loop < delIndexs.Count && i == delIndexs[loop])
                {
                    loop++;
                    continue;
                }
                trIndexs.Add(indexs[i]);
            }
            return trIndexs;
        }

        /// <summary>
        /// 把GBK编码对应的Unicode编码写进文件里 按照升序排列
        /// 并按照相同的位置在令一个文件里写入Unicode码对应的GBK编码
        /// </summary>
        /// <param name="uniCodes">unicode编码表</param>
        /// <param name="file1">unicode编码表按照16进制的方式写入文件中用逗号分隔</param>
        /// <param name="file2">unicode编码表对应位置的gbk编码,按照16进制方式写入文件</param>
        public void Unicode2GBKMap(int[] uniCodes, string file1, string file2)
        {
            string rn = "";
            int cnt = 0;
            StreamWriter sw1 = new StreamWriter(file1);
            StreamWriter sw2 = new StreamWriter(file2);
            Array.Sort(uniCodes);

            for (int i = 0; i < uniCodes.Length; i++)
            {
                cnt++;
                rn = "";
                if (cnt % 10 == 0)
                {
                    rn = "\r\n";
                }
                string unCodeStr = String.Format("0x{0},{1}", uniCodes[i].ToString("X"), rn);
                sw1.Write(unCodeStr);

                int gbCode = Unicode2GBK(uniCodes[i]);
                string gbCodeStr = string.Format("0x{0},{1}", gbCode.ToString("X"), rn);
                sw2.Write(gbCodeStr);
            }

            sw1.Close();
            sw2.Close();
            MessageBox.Show("转换完成:" + cnt.ToString());
        }

 

                以上贴的是主要的代码,具体界面代码,请直接下载代码工程包,其中效果展示如下:

                代码下载:http://download.youkuaiyun.com/detail/devcopper/5356713

 

 

 

 

参考资料:http://baike.baidu.com/view/931619.htm?fromId=25421&redirected=seachword

一文读懂编码(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE) 第一二个字节、第三四个字节的起始部分的都是”110″和”10″,正好与UTF8规则里的两字节模板是一致的,于是再次打开记事本 时,记事本就误认为这是一个UTF8编码的文件,让我们把第一个字节的110和第二个字节的10去掉,我们就得到了”00001 101010″,再把各位对齐,补上前导的0,就得到了”0000 0000 0110 1010″,不好意思,这是UNICODE的006A,也就是小写的字母”j”,而之后的两字节用UTF8解码之后是0368,这个字符什么也不是。这样做,也有弊处,尤其体现在网页中。 阅读详情

相关推荐

GB2312于Unicode互转C语言程序(完整VS2010工程)

GB2312于Unicode互转C语言程序(完整VS2010工程) 能够直接使用。

浅谈unicode和gb2312之间的转换

浅谈unicode和gb2312之间的转换     我先说,这两个是没有线性的转换关系,不能通过程序加加减减弄出来,只能硬性的对应,今天看了一天,终于知道了,哎。。。 1. Unicode概念    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个

易时能专栏 1万+

ChatIE:基于ChatGPT的零样本信息抽取实战指南

信息抽取是自然语言处理中的核心任务,旨在从非结构化文本中自动识别并结构化关键信息,如实体、关系及事件。传统方法依赖大量标注数据训练专用模型,流程复杂且成本高昂。随着大语言模型的发展,通过提示工程引导模型理解任务,实现了无需训练数据的零样本抽取能力,极大降低了技术门槛与应用成本。这种范式将信息抽取重构为多轮对话问题,通过分阶段提问引导模型逐步输出结构化结果,在快速原型验证、领域适配及小规模数据探索中展现出显著技术价值。本文以ChatIE项目为例,深入解析如何利用ChatGPT API,通过精心设计的提示词与两

weixin_30540691的博客 404

字符编码详解:ASCII、GB2312、GBK、Unicode

无

m0_47584501的博客 4715

Julia Ann老司机管理系统

https://content.badgirlsusa.com/Julia_Ann-Sexy_Julia_Ann_Fucks_A_Lil_Elf's_Big_Cock_/Julia-Ann-Naughty-America-%E6%80%A7%E6%84%9F%E7%9A%84%E8%A3%98%E8%8E%89%E5%A9%AD%E5%AE%89%E4%BA%82%E6%90%9E-lil-%E7%B2%BE%E9%9D%88%E7%9A%84%E5%A4%A7%E5%85%AC%E9%9B%9E-2020

www_oracle_com的博客 22万+

车载监控系统升级指南:如何用XS9950A替换TP9950实现高清视频解码(附配置代码)

本文提供了从TP9950升级至XS9950A车载视频解码芯片的完整实战指南。详细解析了硬件设计调整、PCB布局要点,并重点分享了通过I2C配置寄存器实现高清HDCCTV视频解码与同轴音频集成的软件驱动代码与调试技巧,助力工程师平滑完成系统升级。

weixin_29268637的博客 364

ASCII、GB2312、GBK、GB18030、Unicode、UTF-8、BIG5 编码分析

“锟斤拷,烫烫烫烫烫~~~~” ASCII、gb2312、gbk、utf-8、Unicode编码详解

小清华的小哥哥 8915

从零开始安装pytorch(包含GPU和CPU版本的安装)

Pytorch是。

qiaoxinyu1989的博客 8万+

GB2312 Unicode转换表

源程序编辑软件将中文转化为GB2312编码,再下列的GB2312 Unicode转换表转为unicode。 实现2维数值,GB2312编码为递增,适合用二分法查找由GB2312码找Unicode码。 只含基本的汉字,符号未包括。 说明unit16 为16位的无符号整数unsigend short int #typedef  unsigned short int   u

瑞风轻拂 1万+

Anaconda下安装LabelImg

Anaconda下安装LabelImg

LYH8543的博客 756

索尼IMX316 标定_ToF模块相机校准

很多东西一开始给出去的并不是最优的方案,而是在客户端支持中,以及在持续不断的芯片验证中,发现还可以这么做,还能够再提升Sensor的性能,所以说这是一个持续的过程。曾经听说过一个故事,在某厂里ST产品一直作为第一供应商多年,然后近段时间即将被新兴公司的ToF产品所打败,性能报告已经出来,但是ST并没有更新产品,而是在原有产品更新了固件以及标定流程,此时产品的性能又是超越其他供应商的产品。相机矩阵不考虑镜头失真,因为理想的针孔相机没有镜头。为了准确地代表一个真实的相机,相机模型包括径向和切向的镜头畸变。

dream it possible 1154

我所了解的GB2312、Unicode、GBK、UTF-8、BIG5等编码

小编一直对文字编码感到模糊,在学习、编程等过程中也经常会遇到与之相关的问题,无奈只能问百度。于是,为解决这一问题,小编花了一些时日了解和学习这些编码,整理出了这些编码的“性格特点”,“兴趣爱好”等等(文章中可能不全面,接受建议)。 有关文章参见:趣谈unicode,ansi,utf-8,unicode big endian这些编码有什么区别。 在这之前,我得先提一下ASCII码(American ...

Yangchenju的博客 1万+

图解B+树的插入过程

B+ 树在现代数据库中很常见,如果我们了解它,在工作中可能对性能优化会有更好的帮助! 最近我一直在思考 B+ 树的高度是由什么决定的。知道我了解了 B+ 树的插入过程,才有一种恍然大悟的感觉! 网上的一些资料杂乱无章,不同的数据库可能还有对 B+ 树有不同的实现。但是万变不离其宗,B+ 树的定义,大致如下所示: 总结一下,B+ 树有下面 5 个重要的特点。 B+ 树包含 2 种类型的结点: 内部结点(也称索引结点)和叶子结点。 根结点本身即可以是内部结点,也可以是叶子结点。 根结点的关键字个数最

愿君出走半生,归来时仍是少年 2134

GB2312/GBK 与 Unicode 的关系

它们是独立的中文字符编码标准,与 Unicode 属于不同的体系,但可以通过转换规则与 Unicode 互相对应。虽然二者不属于同一体系,但可以通过。

u014094704的博客 817

Plecs电力电子仿真专业教程-第一季 第一节 Plecs简介

Plces 电力电子仿真专业教程系列依托专业的电力电子仿真软件Plecs对各种电力电子常用的拓扑及实际设计的方案进行系统及仿真与软件代码仿真实践。通过对各种电路仿真原理的讲解及专业C语言代码程序的编写,提升学员的系统设计能力,软件编程能力与理论分析能力。

3641

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

unicode、GB2312、GBK

本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等。     在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是"d6d0 cec4",Unicode编码为"4e2d 6587",UTF编码就是"e4b8ad e69687"。注意,这两个字没有iso8859-1编码,但可以用iso8859-1编码来"表示"。 2. 编码基本知识     最

你的爱是我走不出的银河! 896

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Unicode、GB2312、GBK和GB18030中的汉字

Unicode、GB2312、GBK和GB18030中的汉字 GB18030有两个版本:GB18030-2000和GB18030-2005。GB18030-2000是GBK的取代版本,它的主要特点是在GBK基础上增加了CJK统一汉字扩充A的汉字。GB18030-2005的主要特点是在GB18030-2000基础上增加了CJK统一汉字扩充B的汉字。本文数一数GB18030中的汉字,也顺便看看其它标

KFPA的博客 2531

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

编码格式简介(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)

转发:http://blog.jobbole.com/30526/ 来源:潜行者m 的博客 编码一直是让新手头疼的问题,特别是 GBK、GB2312、UTF-8 这三个比较常见的网页编码的区别,更是让许多新手晕头转向,怎么解释也解释不清楚。但是编码又是那么重要,特别在网页这一块。如果你打出来的不是乱码,而网页中出现了乱码,绝大部分原因就出在了编码上了。此外除了乱码之外,还会出现一些其他问题

ldanduo的专栏 11万+

Java 编码格式认识:ASCII GB2312 GBK Unicode UTF

Sunrise的专栏 1022

gb2312 gbk unicode utf url base64编码

UTF-8 没有字节序问题,上述字符只是用来标识它是 UTF-8 文件,而不是用来说明字节顺序的。前面提到过,“中” 字的 Unicode 码是 4E2D, 它小于 0x10000,根据表格可知,它的 UTF-16 编码占两个字节,并且和 Unicode 码相同,所以 “中” 字的 UTF-16 编码为 4E2D。BOM 是 byte-order mark 的缩写,是 “字节序标记” 的意思, 它常被用来当做标识文件是以 UTF-8、UTF-16 或 UTF-32 编码的标记。

要把所有那些负面的信息当做对自身行为的评价,而不是对自身价值的评判。 1468

各种编码格式(GB2312,GBK,GB18030,unicode,utf-8)之间的关系

汉字常用编码格式 为了在屏幕上显示字符。需要下面几个步骤: 制作所有字符对应的字模。比如大写字母A长什么样。这个模样就是最终显示在屏幕上图形,即我们看到的字符A。 为对所有的字符进行编码。比如大写字母A的编码为0x41. 由于字符的数量远大于一个字节,所以当字符编码进行存储、传输时,需要给它们指定格式。如怎样确定某个字符的编码是一字节还是多字节。如0xC0 0xEE代表一个字符的编码(0xC0E...

guoweilkd的博客 2万+

ASCII 、GB2312、GBK、GB18030、unicode、UTF-8字符集编码

ASCII字符集编码 ASCII字符集编码ASCII码是7位编码,编码范围是0x00-0x7F。ASCII字符集包括英文字母、阿拉伯数字和标点符号等字符。其中0x00-0x20和0x7F共33个控制字符。 只支持ASCII码的系统会忽略每个字节的最高位,只认为低7位是有效位。HZ字符编码就是早期为了在只支持7位ASCII系统中传输中文而设计的编码。早期很多邮件系统也只支持ASCII编码,为了传输中文邮件必须使用BASE64或者其他编码方式。 GB2312字符集编码 GB2312 是汉字字符集和.

my_angle2016的博客 1752

关于unicode、utf8、utf16、gb2312和GBK的一些理解

新鲜博客第一篇。。。哈哈。。。延续了网易博客上的书写习惯。。。 说正题了。。。。先从最简单的说起。。。ASCII码。。。大家都知道的了。。。用7位的编码如果只是代表英文字母和标点符号。。。还是可以的。。。。但是如果想要表达汉字或者其他字符。。。就远远不够了。。。因此就出现了很多其他的编码。。。如下。。。。。(1)为了处理汉字,于是出现了用于简体中文的GB2312和用于繁体中文的bi

神的孩子 803

简单讲解ANSI Unicode、GBK、GB2312

字符编码

qq_42317817的博客 2491

GB2312,GBK,Unicode的理解

现在进行web开发,中文乱码经常遇到,是什么原因形成的乱码?其实,乱码问题是由于客户端请求的编码和服务器端响应的编码不一致导致的.     就比如你去一家美国的餐馆吃饭,对着服务员说中文,人家铁定听不懂,如果服务员硬给你上菜,那么上的菜肯定不是你要的那些,这就是顾客请求的编码和服务员响应的编码不一致,会出现乱码的.从现实生活的角度来看,你有几种解决方法.一是改说英语,那么就不会有问题,二

铃铛 3371
上一篇: Setup Factory打包程序
下一篇: 四叉树编码实现
修哥
博客等级 码龄14年 71粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值