toFrankie / blog

种一棵树,最好的时间是十年前。其次,是现在。
20 stars 1 forks source link

字符与字符集 #316

Open toFrankie opened 1 year ago

toFrankie commented 1 year ago

计算机存储单位

在此之前,有必要简单了解下计算机中常用的存储单位。

比特

比特」是计算机科学中的概念,是数据存储和传输的最小单位,有且仅有 01 两个值。音译自 bit,是 binary digit 的简写。

这样的 01 称为一位,常用 1b1bit 表示(小写字母)。一位可以表示两种状态。比如,用一位表示开关的状态,0 表示打开,1 表示关闭。

既然 1bit 可以表示两种状态,那么多个 bit 组合,便可以表示 N 种状态。我们在计算机中看到的数字、字母、中文、符号、图片以及音频等内容都是由多个二进制数 01 组成的,它们就是以二进制数的形式存储在存储介质上的。

字节

由于 1bit 只能表示两种状态,为了可以更方便地表示多种状态,在计算机中还常用「字节」作为存储单位。一个字节用 1B1Byte 表示(大写字母),由 8bit 组成,可以表示 256( $2^{8}$ )种不同的状态。

字节和比特的换算关系为 1 Byte = 8 bit。

字符与字符集

字符」是相对于人类自然语言来说的,是一种更友好的表示方式,可以是一个阿拉伯数字、英文字母、汉字、片假名、标点符号等。除此之外,还有像表示回车、换行、制表等控制字符。「字符集」则顾名思义,是由多个字符组成的集合。

我们知道,计算机中存储的所有东西本质上都是 01 组成的。那么,英文字母 A 在计算机上存储的二进制数是 01000001,是 01000010,还是其他呢?理论上都是可以的,但为了统一:

A 对应为 01000001 B 对应为 01000010 C 对应为 01000011 .....

这些映射关系由字符集规定好的。也就是说,只要遵循同一字符集,那么字符 A 在存储时总是 01000001。相反地,计算机读取到二进制数 01000001 时,总会“翻译”为 A

A01000001 的过程称为「字符编码」,把字符集中的字符编码为指定集合中某一对象,以便计算机存储、传输和转换它们。反之,则为解码。

常见字符集

计算机是美国人发明的,他们的语言体系中只有数字、英文字母以及标点符号,因此他们制定的 ASCII 字符集,只包含数字、英文字母、标点符号以及一些控制字符。在当时,这对他们来说是足够的。

但随着计算机在全世界流行,ASCII 字符集无法正确地表示其他自然语言的字符,比如中文、日文等。为了适应各类语言,衍生出一系列的字符集,比如我国的 GB2312 和 GBK 字符集。

然而,很多字符集是基于 ASCII 的,且不兼容其他字符集,无法在全世界范围内使用。随着国际化流行,这样下去肯定不行啊,于是一个非营利组织 Unicode 联盟站了出来,扬言要制定一套适用于多国语言的字符转换标准,积极与 ISO、W3C、ECMA 等各标准制定组织合作,并取得了成功,对国际化和本地化产生重大影响。

ASCII 字符集

ASCII」全称是美国标准信息交换代码(American Standard Code for Information Interchange, ASCII),由美国国家标准协会(American Nation Standard Institute, ANSI)制定。

在标准 ASCII 中,每个字符用一个字节表示,即 8bit。但其最高位(首位)是 0,并没有被利用上,可表示 128 个字符。

  • 编号范围为 0 ~ 31 和 127 的是不可见的控制字符,共 33 个字符。比如回车符、换行符、退格符等。
  • 编号范围为 32 ~ 126 是可显示字符,共 95 个字符。比如空格、A、B 等。

其优点是每个字符只占用一个字节,但缺点也非常明显,只能显示大小写英文字母、数字以及标点符号,对于汉字、西欧语言显示无能为力。

EASCII 字符集

由于 ASCII 最高位没有利用上,只表示 0x00 ~ 0x7F(十进制 0 ~ 127)共 128 个字符。于是其他国家盯上了 0x80 ~ 0xFF(十进制 128 ~ 255)这 128 个字符,并扩展出一系列的字符集。

EASCII」(Extended ASCII)就是其中之一,兼容 ASCII 的扩展字符集。尽管它跟 ASCII 一样,都是单字节编码,但可表示 256 个字符,比 ASCII 多了一倍。扩展部分包括表格符号、计算符号、希腊字母和特殊的拉丁符号。

基本上已被淘汰,其标准化程度也没有 ISO 8859 好。

ISO 8859 系列字符集

ISO/IEC 8859」是由国际标准化组织(ISO)和国际电工委员会(IEC)联合制定的一系列字符集标准。同样是扩展自 ASCII 字符集,单字节编码,统一了此前各国各语言单独编码的局面。

目前,ISO 8859 系列包含了以下 15 个字符集,其中 ISO 8859-12 已废除(更多)。

MySQL 8.0 之前的默认字符集 Latin-1 就是 ISO/IEC 8859-1。

这系列字符集规定,每个字符集最多可定义 96 个字母或符号,在 0xA0 ~ 0xFF(十进制 160 ~ 255)范围内。其中 0xA0 位置是不换行空格(Non-breaking space)。

目前这份标准也不再更新了。

USC 通用字符集

通用字符集」(Universal Character Set, UCS)是由 ISO 制定的 ISO 10646 标准所定义的标准字符集。原先维护 ISO 8859 标准的工作组已解散,目前该委员会另一工作组致力于 ISO 10646 的开发。

通用字符集包含了已知的所有字符,比如拉丁字母、希腊字母、阿拉伯字母、汉字、假名以及大量的符号等。它给每个字符赋予一个正式的名字,在字符的十六进制数前面加上 U+ 表示,比如: U+0041 表示字符 A

历史上,制定的 ISO 10646 标准的工作组和 Unicode 联盟是两个独立的组织,起初它们各自制定的标准并不相同,后来两个项目的组织者意识到世界上并不需要两个不兼容的字符集,于是两者进行合作,从 Unicode 2.0 起,Unicode 采用了与 ISO 10646 相同的字库和字码。在两个标准中,所有字符都在相同的位置并且具有相同的名字。

但 Unicode 使用更为广泛,有一统江湖的意思。

GB 2312、GBK 和 GB 18030 字符集

在西方语言体系中,使用单字节编码可以表示 256 个字符,就算加上其他一些标点符号,对于他们来说是足够的。但对于我国的汉字来说显然是不够的。

就 2013 年国务院公布的《通用规范汉字表》来说,其中收录了 8105 个字,其中 3500 个常用字,3000 个次常用字,1605 个用于满足信息化时代和专门领域用字需求的字。除简体字之外,还有繁体字、生僻字等。在现代汉语词典第七版收录了约 12000 个汉字。

GB 2312 字符集

GB 2312」又称为 GB/T 2312、GB/T 2312-80 或 GB/T 2312-1980,是由国家标准总局于 1980 年发布的信息交换用汉字编码字符集(基本集)。该字符集适用于中国大陆、新加坡等地。

兼容 ASCII 字符集,但不兼容 ISO 8859 系列字符集。

冷知识,其中「GB」是「国家标准,国标」二字的拼音首字母:

  • GB 表示强制性国家标准。
  • GB/T 表示推荐性国家标准。
  • GB/Z 表示指导性技术文件。

GB 2312-1980 自 2017 年 3 月 23 日起,转为推荐性标准,编号改为 GB/T 2312-1980。

GB 2312 标准收录了包含汉字、数字、序号、拉丁字母、希腊字母、俄文字母、日文假名等 7445 个图形字符,其中有 6773 个。基本满足了汉字使用场景。

对于人名、地名、古汉语等方面出现的罕见字、繁体字,GB 2312 并不能处理。后来衍生出 GBK 等汉字字符集。

GBK 字符集

GBK」意为国家标准扩展,是国、标、扩三字拼音首字母的缩写。由国家技术监督局标准化司和电子工业部科技与质量监督司于 1995 年 12 月 15 日公布,它是技术规范指导性文件,不属于国家标准。由于计算机的普及,GB 2313 收录的字符不够用,于是 GBK 字符集出现了,后者共收录了 21886 个汉字和符号。

GBK 向下完全兼容 GB 2312 编码。

GBK 与 GB 2312 一样,采用了双字节编码方式,但编码方式不同,因此它们可存储的字符数量并不相同。

GB 18030 字符集

GB 18030」是由国家质量技术监督局于 2000 年 3 月 17 日推出的标准,以取代 GBK。

GB 18030 完全兼容 GB 2313,基本兼容 GBK,并支持 Unicode 所有码位。

GB 18030 采用变长多字节编码,每个字符可以由 1 个、2 个或 4 个字节组成,编码空间庞大,最多可定义 160 多万个字符。

Unicode 字符集

未完待续...