[转帖]彻底搞明白 GB2312、GBK 和 GB18030
https://zhuanlan.zhihu.com/p/453675608
日常工作的过程中,关于字符编码的问题经常让人头疼不已,这篇文章就来捋一捋关于 GB2312、GBK、GB18030 相关的知识 以及它们和 Unicode 的关系
简介
- GB2312
1980 年,中国发布了第一个汉字编码标准,也即 GB2312 ,全称 《信息交换用汉字编码字符集·基本集》,通常简称 GB (“国标”汉语拼音首字母), 共收录了 6763 个常用的汉字和字符,此标准于次年5月实施,它满足了日常 99% 汉字的使用需求
- GBK
由于有些汉字是在 GB2312 标准发布之后才简化的,还有一些人名、繁体字、日语和朝鲜语中的汉字也没有包括在内,所以,在 GB2312 的基础上添加了这部分字符,就形成了 GBK ,全称 《汉字内码扩展规范》,共收录了两万多个汉字和字符,它完全兼容 GB2312
GBK 于 1995 年发布,不过它只是 "技术规范指导性文件",并不属于国家标准
- GB18030
GB18030 全称《信息技术 中文编码字符集》 ,共收录七万多个汉字和字符, 它在 GBK 的基础上增加了中日韩语中的汉字 和 少数名族的文字及字符,完全兼容 GB2312,基本兼容 GBK
GB18030 发布过两个版本,第一版于 2000 年发布,称为 GB18030-2000,第二版于 2005 年发布,称为 GB18030-2005
编码方式
ASICII、GB2312、GBK、GB18030 之间的关系可以用下图表示

GB2312 兼容 ASICII 编码, GBK 兼容 GB2312 编码,GB18030 兼容 GB2312 编码 和 GBK 编码
实际生活中,我们用到的 99% 的汉字,都属于 GB2312 编码范围 ,GB2312 每个编码对应的是哪个汉字可以参考 GB2312简体中文编码表, GBK 编码可以参考 GBK编码表, GB18030 可以参考 GB18030-2005 文档
GB2312 编码
GB2312 把每个汉字都编码成两个字节,第一个字节是高位字节,第二个字节是低位字节
GB2312 为了兼容 ASICII ,其编码需要进行一些转换才能避免和 ASICII 编码重叠,转换的过程涉及到区位码和国标码的概念,下面说明转成内码的过程
- 区位码
GB2312 对汉字进行了分区处理,每个区含有 94 个汉字或者字符,总共有 94 个区,每个汉字或者字符都对应一个 分区编号和分区内的位置编号,称为 区位码
比如:汉字 "中" 字的 分区编号是 54,分区内位置编号是 48,所以,"中" 字的区位码是 54 48
- 国标码
国标码 也叫 交换码,用于交换文件所使用的编码,在早期,不同的操作系统可能使用不同的内码,如果它们之间要交换文件,则会发生乱码的现象,当时的解决方法是交换文件之前先转成交换码再交换,接收者收到之后再转成内码
交换码是比较早期的一种方案,目前系统大都采用内码作为交换码
ASICII 码为 0- 31 的这 32 个字符是不可显示的字符,为了避免和这些字符的码点冲突,将 分区编号和分区内位置编号都加上 32 ,把这个转换的结果称为 国标码
比如:汉字 "中" 字分区编号是 54,分区内位置编号是 48,加上 32 之后,分区编号是 54 + 32 = 86, ,分区内位置编号是 48 + 32 = 80,所以 "中" 字 的国标码是 86 80
- 内码
国标码 和 ASICII 码还是存在一定的重复,比如 "中" 字 的国标码是 86 80,对应第一个字节是 86,第二个字节是 80,而在 ASICII 码中它们分别代表大写字母V 和 大写字母 P,这就无法区分它们到底是一个汉字,还是两个字母
为了解决这一点,把国标码中的每个字节的最高位置为 1,也即相当于每个字节都加上 128 ( 2的7次方 ),还是以 "中" 字为例,它的 国标码是 86 80,加上 128 后, 第一个字节是 86 + 128 = 214, 第二个字节是 80 + 128 = 208,转化成 16 进制是 0xD6 0xD0 ( 214 的十六进制是 0xD6, 208 的十六进制是 0xD0 )
国标码的每个字节都加上 128 后,得到国标码的机内码,简称 内码,汉字是以内码的形式在计算机中存储和传播的
上面介绍 区位码 和 国标码,主要是是为了说明 汉字内码是如何一步一步发展而来的
可以看出,汉字的 区位码 + 32 + 128 就得到了内码,进一步简化,区位码 + 32 + 128 = 区位码 + 160 = 区位码 + 0xA0(128 的十六进制) , 因此 内码 = 区位码 + 0xA0
比如:"中" 字的区位码是 54 48,对应的十六进制是0x36 0x30,因此它的内码为 (0x36 + 0xA0) (0x30 + 0xA0),也即 0xD6 0xD0
关于汉字的区位码请参考:汉字区位码
GB2312 有效的编码范围如下图所示

上图中 红色栏 表示 ASICII 的编码范围,绿色栏表示 GB2312 编码范围
GBK 编码
和 GB2312 一样,GBK 也是双字节编码,为了向下兼容 GB2312, GBK 使用了 GB2312 没有用到的编码区域,总的编码范围是: 第一个字节 0x81–0xFE,第二个字节 0x40–0xFE, 具体的编码范围细分如下

上述表格中,红色栏是 GBK 中包含的 GB2312 以及 ASICII 的编码范围,它们的编码范围保持不变
绿色栏的是 GBK 新增的编码范围
紫色栏是 用户自定义编码范围
GB18030 编码
与 GBK 不同的是,GB18030 是变长多字节字符集,每个字或字符可以由一个,两个或四个字节组成,所以它的编码空间是很大的,最多可以容纳 161 万个字符
由于需要兼容 GBK,四个字节的前两个字节和 GBK 编码保持一致,GB18030 具体的编码范围如下

GB18030 与 Unicode
GB18030 和 Unicode 相当于两套单独的编码体系,它们都对世界上大部分字符进行编码,赋予每个字符一个唯一的编号,只不过对于同一个字符,GB18030 和 Unicode 对应的编号是不一样的, 比如:汉字 "中" 字的 GB18030 编码是 0xD6D0, 对应的 Unicode 码元是 0x4E2D, 从这一点上可以认为 GB18030 是一种 Unicode 的转换格式
注意:要表达 Unicode 的编码格式才真正算得上 Unicode 转换格式,所以严格意义上说 GB18030 并不是真正的 Unicode 转换格式
GB18030 既是字符集又是编码格式,也即字符在字符集中的编号以及存储是进行编码用的编号是完全相同的,而 Unicode 仅仅是字符集,它只规定了字符的唯一编号,它的存储是用其他的编码格式的,比如 UTF8、UTF16 等等
既然 GB18030 和 Unicode 都能表示世界上大部分字符,为什么要弄两套字符集呢,一套的话不更有利于信息的传播吗?
1、在 Unicode 出现之前,没有统一的字符编码,每个操作系统上都有自己的一套编码标准,像早期的 window 上需要安装字符集,才能支持中文,这里的字符集就是微软自定的标准,换个其他系统就会失效
2、对于大部分中文字符来说,采用 GB18030 编码的话,只需两个字节,如果采用 UTF8 编码,就需要三个字节, 所以用 GB18030 存储和传输更节省空间
ASICII、GB2312、GBK、GB18030 以及 UTF8 的关系
它们的关系如下图

由上图可知,GB2312、GBK、GB18030 以及 UTF8 共同点是都兼容 ASICII
全角和半角字符
使用输入法输入字符的时候,有全角和半角之分,对于同一个字符,全角和半角对应的码点是不一样的
下面列出了一些字符的全角和半角的外观截图

半角是 ASICII 码中的字符,对应的编码范围是 0x00 - 0x7F,每个字符占一个字节
全角是 GB2312 中的字符,每个字符占用两个字节 ,其编码范围和半角字符范围是没有重叠的
对于汉字来说,是没有全角和半角之分的
比如:上图中 @ 符号,全角的编码是 0xA3C0,占两个字节, 半角的编码是 0x40,占一个字节
通过内码输入汉字的方法
有时需要输入一些特殊的字符,比如 带圆圈的数字字符 ①,一般需要借助输入法的小键盘来输入
这里介绍一种使用字符内码来快速输入的方法: 按住 Alt 键不放,输入字符内码的十进制,输入完后松开 Alt 键
例如,输入带圆圈的数字 ② 的步骤
1、查找带圆圈数字 2 的字符的编码 0xA2DA,十进制是 41690
2、按住 Alt 键不放,输入 41690,松开 Alt 键
3、输入完毕,这时就会出现字符 ②
一般 Linux的 SSH 连接工具 或 windows 上的记事本,都支持内码输入
[转帖]彻底搞明白 GB2312、GBK 和 GB18030的更多相关文章
- BIG5, GB(GB2312, GBK, ...), Unicode编码, UTF8, WideChar, MultiByte, Char说明与区别
汉语unicode编译方式,BIG5是繁体规范,GB是简体规范 GB是大陆使用的国标码,BIG5码,又叫大五码,是台湾使用的繁体码. BIG5编码, GB编码(GB2312, GBK, ...), U ...
- [转帖]Nginx为什么高效?一文搞明白Nginx核心原理
Nginx为什么高效?一文搞明白Nginx核心原理 咔咔侃技术 2019-09-06 15:37:00 https://www.toutiao.com/a6733057587622707724/ Ng ...
- 字符集、字符编码、国际化、本地化简要总结(UNICODE/UTF/ASCII/GB2312/GBK/GB18030)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 普通的linux 和 普通的windows. ...
- python中文字符乱码(GB2312,GBK,GB18030相关的问题)
转自博主 crifan http://againinput4.blog.163.com/blog/static/1727994912011111011432810/ 在玩wordpress的一个博客搬 ...
- 中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030
中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030 cp936是微软自己发布的用在文件系统中的编码方式.而bg2312是中国国家标准.我明白mount -t vfa ...
- ASCII,unicode, utf8 ,big5 ,gb2312,gbk,gb18030等几种常用编码区别(转载)
原文出处:http://www.blogjava.net/xcp/archive/2009/10/29/coding2.html 最近老为编码问题而烦燥,下定决心一定要将其弄明白!本文主要总结网上一些 ...
- [转]各种编码ANSI、GB2312、GBK、GB18030、UNICODE以及UTF-8傻傻分不清!
计算机编程中的编码一直是让新手非常头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别,更是让许多新手晕头转向,怎么解释也解释不清楚,看一遍貌似懂了,但实际使用的时候又 ...
- 各种字符编码方式详解及由来(ANSI,UNICODE,UTF-8,GB2312,GBK)
一直对字符的各种编码方式懵懵懂懂,什么ANSI UNICODE UTF-8 GB2312 GBK DBCS UCS……是不是看的很晕,假如您细细的阅读本文你一定可以清晰的理解他们.Let's go! ...
- 字符编码ANSI、ASCII、GB2312、GBK、GB18030、UNICODE、UTF-8小结
编码和解码可以理解成二进制和字符(广义的字符,包括汉字等)的映射表,编码即从字符映射至二进制,解码则为逆过程. 1.英语字符编码ASCII 开始计算机只在美国用.8字节一共可以组合出256(2的8次方 ...
- 【已解决】python中文字符乱码(GB2312,GBK,GB18030相关的问题)
http://againinput4.blog.163.com/blog/static/1727994912011111011432810/ [已解决]python中文字符乱码(GB2312,GB ...
随机推荐
- 如何用axios加后端数据库传值给前端
小杰笔记: 如何用axios : 第一步:编写数据库实体类 @Data @AllArgsConstructor @NoArgsConstructor public class User { priva ...
- JavaFx 打开一个新窗口和窗口交互(四)
JavaFx 打开一个新窗口和窗口交互(四) JavaFX 从入门入门到入土系列 前面我演示的demo都是单个窗口,那么如何实现多个窗口呢?使用Stage secondStage = new Stag ...
- vue上传文件显示进度条,当上传完成后间隔一秒进度条消失
<template> <el-upload class="avatar-uploader" action="api/file/upload" ...
- 为什么OpenAPI是未来企业数字化转型的决定性因素?
本文分享自华为云开发者联盟公众号<为什么OpenAPI是未来企业数字化转型的决定性因素?>. 随着数字经济不断发展升级,数据互通.万物互联正在逐步成为IT产业发展的主旋律,企业数字化转型也 ...
- 云图说|ModelArts开发环境,让AI开发、探索、教学更简单
摘要:ModelArts开发环境,以云原生的资源使用和开发工具链的集成,目标为不同类型AI开发.探索.教学用户. 本文分享自华为云社区<[云图说]| 第280期 ModelArts开发环境,让A ...
- 数仓出现“wait in ccn queue”的时候,怎么迅速定位处理?
摘要:现网在使用动态负载管理的时候,经常出现很多wait in ccn的情况,大家处理起来就会认为是hung住或者怎么着了,很着急,但wait ccn其实就是一个等待资源的状态,在此总结一个ccn问题 ...
- “/usr/bin/hdp-select”, line 226 print “ERROR: Invalid package – “ + name ^ SyntaxError: Missing parentheses in call to ‘print’. Did you mean print(“ERROR: Invalid package
spark-submit时报错 python升级3.7引起 恢复2.7正常
- Snack3 3.1.10的新特性及应用
<dependency> <groupId>org.noear</groupId> <artifactId>snack3</artifactId& ...
- Kubernetes(K8S) Pod 介绍
Pod 是 k8s 系统中可以创建和管理的最小单元, 是资源对象模型中由用户创建或部署的最小资源对象模型, 也是在 k8s 上运行容器化应用的资源对象, 其他的资源对象都是用来支撑或者扩展 Pod 对 ...
- 聊聊大语言模型(LLM)的 10 个实际应用
近期,苹果公司正在悄悄研究可以挑战的 OpenAI.谷歌和其他公司的 AI 工具,建立了自己的框架来创建大语言模型,并创建了一个聊天机器人服务,一些工程师称之为"Apple GPT" ...