汉字编码及区位码查询算法
为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准:GB2312-80《信息交换用汉字编码字符集》基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,简称GB18030。由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个"区",每一列称为一个"位",因此,这个方阵实际上组成了一个有94个区(区号分别为0 1到94)、每个区内有94个位(位号分别为01到94)的汉字字符集。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的"区位码"。在汉字的区位码中,高两位为区号,低两位为位号。在区位码中,01-09区为682个特殊字符,16-87区为汉字区,包含6763个汉字 。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列)。
从汉字到区位码的转换。区位码是与汉字一一对应的编码,用四位数字表示, 前两位从01 到94称区码,后两位从01到94称位码。 一个汉字的前一半为“160+区码”的字符,后一半为“160+ 位码”的字符。例如:“刘”的区位码是 3385,其意为区码33位码85,它是由160+33=193和160+85=245的两个字节组成。即 C1F5,它就是汉字的 gb2312 编码。
下面程序将汉字 gb2312 转为相应的区位码:
#include <iostream>
#include <iomanip>
{
// temp[0] 为高字节,temp[1] 为低字节
// 当输入单个 ascii 字符时,只存进 temp[0]
// 当输入的不是中文或单个 ascii 字符时,程序退出
unsigned char temp[2];
cin >> temp;
while(temp[1])
{
cout << setw(2) << setfill('0') << temp[0] - 160; // 高 2 位
cout << setw(2) << setfill('0') << temp[1] - 160 << endl; // 低 2 位
temp[1] = 0;
cin >> temp;
}
return 0;
}
字符编码简介
Unicode是一种字符编码规范。先从ASCII说起。ASCII是用来表示英文字符的一种编码规范,每个ASCII字符占用1个字节(8bits)。因此,ASCII编码可以表示的最大字符数是256,其实英文字符并没有那么多,一般只用前128个(最高位为0),其中包括了控制字符、数字、大小写字母和其他一些符号 。而最高位为1的另128个字符被成为“扩展ASCII”,一般用来存放英文的制表符、部分音标字符等等的一些其他符号。这种字符编码规范显然用来处理英文没有什么问题。(实际上也可以用来处理法文、德文等一些其他的西欧字符,但是不能和英文通用),但是面对中文、阿拉伯文之类复杂的文字,255个字符显然不够用,于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做“GB2312-80”,它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示。但是这个方法有问题,最大的问题就是,中文文字没有真正属于自己的编码,因为扩展ASCII码虽然没有真正的标准化,但是PC里的ASCII码还是有一个事实标准的(存放着英文制表符),所以很多软件利用这些符号来画表格。这样的软件用到中文系统中,这些表格符就会被误认作中文字,破坏版面。而且,统计中英文混合字符串中的字数,也是比较复杂的,我们必须判断一个ASCII码是否扩展,以及它的下一个ASCII是否扩展,然后才“猜”那可能是一个中文字 。
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级。整理这篇文章的动机是两个问题:
使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢?
最近在网上看到一个ConvertUTF.c,实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式,我原来就了解。但这个程序让我有些糊涂,想不起来UTF-16和UCS2有什么关系。
查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些Unicode的细节。写成一篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什么是字节,什么是十六进制。
big endian和little endian是CPU处理多字节数的不同方式。例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前面?如果将6C写在前面,就是big endian。若是将49写在前面,就是little endian。
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。
前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容),与GB码不兼容。例如“汉”字的Unicode编码是6C49,而GB码是BABA。
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?Unicode规范中推荐的标记字节顺序的方法是BOM。是Byte Order Mark。BOM是一个有点小聪明的想法:在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
汉字编码及区位码查询算法相关推荐
- 计算机汉字编码不能使用内码,汉字编码及区位码查询算法
为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准:GB2312-80<信息交换用汉字编码字符集>基本集,这个字符集是我国中文信息处理技术的发展基础,也是 ...
- 汉语词典快速查询算法研究
原贴:http://www.nlp.org.cn/docs/docredirect.php?doc_id=1118 汉语词典快速查询算法研究 李江波 周强 陈祖舜 (清华大学智能技术与系统国家重点实验 ...
- 区位码查询系统(vbscript)
区位码查询系统用于查询汉字编码以涂信息卡 <script LANGUAGE="VBScript"> function genqw() str=document.getE ...
- [原] 淘宝SKU组合查询算法实现
前端有多少事情可以做,能做到多好.一直在关注各大公司UED方面的知识,他们也代表了前端的力量,而且也很乐意和大家分享,把应用到项目的知识归类整理,再写成博客搬到网上来,充实这前端的内容,也是为想追寻和 ...
- kmp字符串查询算法
kmp字符串查询算法 1 普通的字符串查询 普通的字符串查询是遍历被查找的字符串,然后和key字符串进行匹配,如果不一致,则,被查找的字符串+1,继续向下遍历. 代码如下: private stati ...
- 常见排序查询算法Java代码实现
1. 排序算法代码实现 /*** ascending sort* 外层循环边界条件:总共需要冒泡的轮数--每一轮都将最大或最小的数冒泡到最后* 内层循环边界条件:冒泡数字移动的边界--最终数字需冒泡到 ...
- sku组合查询算法探索
2019独角兽企业重金招聘Python工程师标准>>> sku组合查询算法探索 http://ued.taobao.org/blog/2012/07/sku-search-algor ...
- java实现找一条转乘次数最少的公交线路?,基于最优换乘次数的城市公交查询算法...
摘要:城市公交查询系统是一个城市非常重要的基础设施,也是城市文明的一个重要标志.该文探讨城市公交查询系统中最优换乘次数的查询算法.算法以图论中邻接矩阵为基础,结合矩阵算术运算的特点和公交查询系统的要求 ...
- 计算机树表查找算法的适用场景,利用基于R-树连续最近邻查询算法来渲染雨滴,形成了逼真的下雨天场景图...
摘要:自动驾驶领域最近的发展表明,这些车辆在不久的将来会出现在每个城市的街道上,而这些城市不会容忍交通事故的发生.为了保证安全需求,自动驾驶汽车和被使用的软件必须在尽可能多的条件下进行详尽的测试.通常 ...
- mysql外码内码定义_刨根究底字符编码之六——简体汉字编码中区位码、国标码、内码、外码、字形码的区别及关系...
简体汉字编码中区位码.国标码.内码.外码.字形码的区别及关系 GB2312.GBK.GB18030等GB类汉字编码方案的具体实现方式是怎样的?区位码是什么?国标码是什么?内码.外码.字形码又是什么意思 ...
最新文章
- 网络推广平台浅析通常网站关键词优化密度该如何把控呢?
- OpenGL textures纹理的实例
- Pycharm 解决pip遇到的错误:module 'pip' has no attribute 'main'
- 创建存储,修改存储_安全地创建和存储密码
- java在一个类里实现存款_用Java编写一个简单的存款
- 电商促销活动那么多,美工需要炫酷海报万能模板!可套用!救急必备!
- 被调用的对象已与其客户端断开连接 win10_【完整案例】基于Socket开发TCP传输客户端...
- 复合存储引擎的设计和实现(包含ORM和内容存储)
- 下载envi中遇到的问题
- Qt中系统屏幕键盘打开与关闭
- Goole helper使用
- 再论iPhone Push Notification
- .NET 经常被面试官问到的问题
- dedecms织梦后台登录一直提示验证码错误
- 内网服务器反弹映射到公网ip去访问
- 数字政府智慧城市数字化运营管理中台建设思路分析
- 计算机专硕考数一英一的学校有哪些,这所211专硕改考数一英一!部分院校初试科目调整...
- 汇编语言的C状态寄存器,汇编指令-状态寄存器、cmp、test、jz等指令详细说明
- background-size:cover与-webkit-background-size
- 【放弃】notepad++ 云同步怎么玩?
热门文章
- vsftpd 安装及简单配置
- openwrt 需要高级浏览器_树莓派 + OpenWrt 实现 BT 下载机
- 天勤数据结构顺序表算法操作含完整测试
- php 跨域解决方案
- 【数字图像处理5.3】SLIC算法 超像素分割(无监督聚类方式)python
- C语言队列单链表实现(通俗易懂),可直接使用
- matlab如何从视频中分离音频文件,如何从视频中分离音频文件 值得收藏
- 【LKJ】LKJ2000型记录装置显示界面说明
- matlab改进中值滤波,求助中值滤波和自适应中值滤波算法错误修改
- php 批量上传图片插件,diyUpload - jQuery多张图片批量上传插件