Featured image of post I don't know what the character encoding is.

I don't know what the character encoding is.

ASCII、Uincode、UTF-8、UTF-16、GBK、GB2312....之间到底有什么关系.

     直到最近,我在windows下读啊写啊文件、编码转来转去,对着屏幕祈祷能打印正确的结果,这样的行为很危险,也让我自愧羞耻、深感无语。编码应该是写代码最基础的事情,然而过去多次遇到此问题我都选择忽视、不想深究厘清编码其中的原理,跟着网上的步骤走走就是了,现在想想实在有违职业素养。就像tag那样,这是我今天之前所不了解的事。

    因此,本文主题是字符编码,旨在厘清ASCII、Uincode、UTF-8、UTF-16、GBK、GB2312….之间的关系。

ASCII

时间: ASCII 编码于 1967 年第一次发布,最后一次更新是在 1986 年。

ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是一套基于拉丁字母的字符编码,共收录了 128 个字符,用一个字节就可以存储,它等同于国际标准 ISO/IEC 646。

GB2312

时间:由中国国家标准总局1980-03-09发布,1981年5月1日开始使用。GB2312编码是第一个汉字编码国家标准。

Tips:根据2017年第7号公告和强制性标准整合精简结论,自2017年3月23日起,该标准转化为推荐性标准,不再强制执行。GB2312-80改为 GB/T 2312-80.

    GB2312全称《信息交换用汉字编码字符集·基本集》,共收录汉字6763个,其中一级汉字3755个,二级汉字3008个。同时,GB2312编码收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。

分区表示:GB2312编码对所收录字符进行了“分区”处理,一共94个区,每个区有94位,共8836个码位。这种表示方式也称为区位码。

1
2
3
4
5
6
01-09区收录除汉字外的682个字符。
10-15区为空白区,没有使用。
16-55区收录3755个一级汉字,按拼音排序。
56-87区收录3008个二级汉字,按部首/笔画排序。
88-94区为空白区,没
“啊”字是GB2312编码中的第一个汉字,它位于16区的01位,所以它的区位码就是1601有使用。

双字节编码:GB2312规定对收录的每个字符采用两个字节表示,第一个字节为“高字节”,对应94个区;第二个字节为“低字节”,对应94个位。所以它的区位码范围是:0101-9494。区号和位号分别加上0xA0就是GB2312编码。

    GB2312是对ACSII的扩充,其完全兼容ACSII编码,英文字母和半角标点符号等用一个字节表示,而ACSII以外的字符,如汉字、全角标点符号,则统一使用两个字节表示。

    GB2312虽然能覆盖99.5%的使用场景,但只考虑了常用的简体中文,总共收录的汉字也不到7000个。而两个字节理论上可以存储6万5千个左右的字符,因此GB2312有大量空间是闲置的。同时期,港澳台地区使用的是BIG5,日韩也是各自有自己得一套规则。因此,为了兼容更多的字符,又诞生了新的汉字编码方案GBK。

GBK

时间:1995年12月15日正式发布1.0版本。 Tips:2000年被GB18030-2000国家强制标准替代,2005年GB18030-2005发布,替代了GB18030-2005

      GBK全称《汉字内码扩展规范》(GBK即“国标”、“扩展”汉语拼音的第一个字母,英文名称:Chinese Internal Code Specification)。是对GB2312编码的扩展,完全兼容GB2312-80标准。GBK编码依然采用双字节编码方案,其编码范围:8140-FEFE,剔除xx7F码位,共23940个码位。共收录汉字和图形符号21886个,其中汉字(包括部首和构件)21003个,图形符号883个。GBK编码支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

GB18030

GB18030-2000

发布时间:2000-03-17 实施时间:2000-03-17

中文标准名称:信息技术 信息交换用汉字编码字符集 基本集的扩充
英文标准名称:Information technology–Chinese ideograms coded character set for information interchange–Extension for the basic set
标准状态:废止

GB18030-2005

发布时间:2005-11-08 实施时间:2006-05-01

中文标准名称:信息技术 中文编码字符集
英文标准名称:Information technology – Chinese coded character set
标准状态:现行

        GB18030编码采用单字节、双字节、四字节分段编码方案。GB18030向下兼容GBK和GB2312编码。国家标准GB18030-2005《信息技术 中文编码字符集》是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,是我国计算机系统必须遵循的基础性标准之一。

GB18030-2000

    GB18030-2000编码标准《信息技术 汉字编码字符集 基本集的扩充》是由信息产业部和国家质量技术监督局在2000年3月17日联合发布的,并且将作为一项国家标准在2001年的1月正式强制执行。GB18030-2000仅规定了常用非汉字符号和27533个汉字(包括部首、部件等)的编码。

GB18030-2000标准收录的字符分别以单字节、双字节和四字节编码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
1、单字节部分
本标准中,单字节的部分收录了GB 11383的0x00到0x7F全部128个字符及单字节编码的欧元符号。

2、双字节部分
本标准中,双字节的部分收录内容如下:
GB 13000.1的全部CJK统一汉字字符。
GB 13000.1的CJK兼容区挑选出来的21个汉字。
GB 13000.1中收录而GB 2312未收录的我国台湾地区使用的图形字符139个。
GB 13000.1收录的其它字符31个。
GB 2312中的非汉字符号。
GB 12345 的竖排标点符号19个。
GB 2312未收录的10个小写罗马数字。
GB 2312未收录的带音调的汉语拼音字母5个以及ɑ 和ɡ 。
汉字数字“〇”。
表意文字描述符13个。
增补汉字和部首/构件80个。
双字节编码的欧元符号。

3 、四字节部分
本标准的四字节的部分,收录了上述双字节字符之外的,
包括CJK统一汉字扩充A在内的GB 13000.1 中的全部字符。

GB18030-2005

    GB18030-2005《信息技术 中文编码字符集》是以汉字为主并包含多种我国少数民族文字的超大型中文编码字符集,其中收入汉字70000余个。在GB18030-2000的基础上增加了42711个汉字和多种我国少数民族文字的编码(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)。增加的这些内容是推荐性的,原GB18030-2000中的内容是强制性的,市场上销售的产品必须符合。故GB18030-2005为部分强制性标准,自发布之日起代替GB18030-2000。

GB18030-2005标准收录的字符分别以单字节、双字节或四字节编码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1、单字节部分
本标准中,单字节的部分收录了GB/T 11383-1989的0x00到0x7F全部128个字符。

2、双字节部分
本标准中,双字节的部分收录内容如下:
GB 13000.1-1993的全部CJK统一汉字字符。
GB 13000.1-1993的CJK兼容区挑选出来的21个汉字。
GB 13000.1-1993中收录而GB 2312未收录的我国台湾地区使用的图形字符139个。
GB 13000.1-1993收录的其它字符31个。
GB 2312中的非汉字符号。
GB 12345 的竖排标点符号19个。
GB 2312未收录的10个小写罗马数字。
GB 2312未收录的带音调的汉语拼音字母5个以及ɑ 和ɡ 。
汉字数字“〇”。
表意文字描述符13个。
对GB 13000.1-1993增补的汉字和部首/构件80个。
双字节编码的欧元符号。

3、四字节部分
本标准的四字节的部分,收录了上述双字节字符之外的,GB 13000的CJK统一汉字扩充A、CJK统一
汉字扩充B和已经在GB13000中编码的我国少数民族文字的字符。GB18030-2005最主要的变化
是增加了CJK统一汉字扩充B。它还去掉了单字节编码的欧元符号0x80)。
GB18030有1611668个码位,在GB18030-2005中定义了76556个字符。
随着我国汉字整理和编码研究工作的不断深入,以及国际标准ISO/IEC 10646的不断发展,
GB18030所收录的字符将在新版本中增加。

Unicode

时间:1990年开始研发,1994年正式发布1.0版本,2021年9月14日发布14.0版本。

    Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集,编码方案等,旨在收录人类目前已知在使用的所有字符,给它们进行统一的分类和编号。unicode的出现使得字符集和编码规则出现区分。unicode只是字符集,只负责给字符编号,不规定具体应当如何编码存储。而此前,无论是ACSII,GB2312,还是GBK,BIG5等,本身既是字符集,也是编码规则。UTF-8, UTF-16, UTF-32就是对unicode的编码规则了。

Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值,这个值称为代码点(code point)。代码点的值通常写成 U+ABCD 的格式。而文字和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets)。顾名思义,UCS-2是用两个字节来表示代码点,其取值范围为 U+0000~U+FFFF。

为了能表示更多的文字,人们又提出了UCS-4,即用四个字节表示代码点。它的范围为 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一样的。

要注意,UCS-2和UCS-4只规定了代码点和文字之间的对应关系,并没有规定代码点在计算机中如何存储。规定存储方式的称为UTF(Unicode Transformation Format)。

UTF-8

时间:1992年09月

UTF-8,Unicode Transformation Format,可变长度编码,通常使用1~4字节为每个字符编码,兼容ASCII编码,这是一种Unicode的一种转换格式。

UTF-8规定,最高位是0开头的,就用一个字节表示,而ACSII正好在其中,因此UTF-8也是兼容ACSII的。最高位是110开头的,就与后一个以10开头的字节拼接为一个整体。最高位是1110开头的,就与后两个以10开头的字节拼接为一个整体。以此类推。

1
2
3
4
5
6
7
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F |                             0xxxxxxx
0000 0080-0000 07FF |                    110xxxxx 10xxxxxx
0000 0800-0000 FFFF |           1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF |  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8 BOM

所谓BOM头(Byte Order Mark)就是文本文件中开始的几个并不表示任何字符的字节。UTF8的BOM头为 0xEF 0xBB 0xBF。

“其实BOM是个小聪明的想法。由于UCS-2没有定义U+FFFE,因此只要出现 FF FE 或者 FE FF 这样的字节序列,就可以认为它是U+FEFF,并且可以判断出是Big Endian还是Little Endian。”

UTF-16

UTF-16使用两个字节表示unicode,是完全对应于UCS-2的,即把UCS-2规定的代码点通过Big Endian或Little Endian方式直接保存下来。UTF-16包括三种:UTF-16,UTF-16BE(Big Endian),UTF-16LE(Little Endian)。

值得一提的是,在Windows上,微软默认把Unicode当作UTF-16进行处理,在选择编码方式时Unicode就相当于选择了UTF-16 LE编码方式。

UTF-32

UTF-32使用4个字节表示unicode,属于定长编码规则。UTF-32的优点是完全根据unicode指定的编号进行编码,不需要做额外的解析工作,缺点是常用的字符有大量高位是被0填充的,浪费存储空间。

名词释义

字符集(Character Set): 一个字符集,这个字符集里面的每个字符都被赋予一个数值型的码点(code point)。又被称为Coded character set, charset,或者code set。

字符(character):字符是文本的最小组成部分。例如A, B, C…就是不同的字符。同理,也是两个不同的字符。但有时候,字符的含义是和你所处的环境有关的。比如“罗马数字1:”就和小写字母I长得一样,但其实它们是两个不同的字符,它们所表示的含义不一样。

编码规则:编码规则:将「码位」转换为字节序列的规则,即解决字符如何存储的问题。

码元(Code Unit,也称“代码单元”)是指某个编码系统里表示的文本中具有最短的比特组合的单元。对于UTF-8来说,码元是8比特长;对于UTF-16来说,码元是16比特长,uft-16还有大端序列和小端序列;对于UTF-32来说,码元是32比特长。

码点(code point):(1)字符集里每个字符都对应一个数值,这个数值就是码点。(2)unicode代码空间(the Unicode codespace)里面的任何值都是码点,范围是0~0x10FFFF。不是所有的码点都有对应的字符。

unicode代码空间(the Unicode codespace):Unicode标准里面用21个bits表示的空间范围。范围是:0~0x10FFFF。

一言以蔽之

最后,不管是写代码也好生活的其他事情也好,一定预知这么做后果是什么,青春赌明天式的做法绝对是危险至极的。

  • unicode是一个标准,包含字符集、字符编码规则,Unicode是一个标准,只规定了字符与码之间的对应关系,具体的存储、传输方式由utf-xxx实现。

  • UTF是Unicode Transfer Format的缩写,字面意思也就是Unicode的传输格式,即UTF-8、UTF-16、UTF-32等均是unicode的编码规则实现方式。

  • 从字节长度的角度来看,UTF-8 是可变长的,通常汉字占3个字节,UTF-16也是变长的,使用一个或两个字节,GB2312/GBK/GB18030等是定长的,汉字和英文都占两个字节。

  • 通常,在windows系统下unicode就是UTF-16,即使这种说法是有误的。

  • windows系统默认的文件存储方式是UTF-16 LE.

  • GB2312、GBK等是对ACSII码的兼容扩展。

  • GB2312、GBK等和UTF-XX的共同点是都兼容ASCII码。

  • UCS-2表示用两个字节来表示一个码点,UCS-4表示用4个字节来表示一个码点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
+--------------------------------------------+
|   GB18030-2005                             |
|                                            |
|     +--------------------------------------+
|     |                                      |
|     |  GB18030-2000                        |
|     |      +-------------------------------+
|     |      |                               |
|     |      |  GBK                          |
|     |      |      +------------------------+
|     |      |      |                        |
|     |      |      |    GB2312              |
|     |      |      |                        |
|     |      |      |        +---------------+
|     |      |      |        |               |
|     |      |      |        |               |
|     |      |      |        |     ASCII     |
|     |      |      |        |               |
|     |      |      |        |               |
+-----+------+------+--------+---------------+

preview

1

参考与延伸

国家标准|GB/T 2312-1980

国家标准|GB 18030-2000

国家标准|GB 18030-2005

GB2312 编码范围, GB2312 编码表

gb2312-1934-3587-2427

哦吼是一首歌。
Built with Hugo
Theme Stack designed by Jimmy