简单理解【编码】和【字符集】

字符集和比较规则简介

字符集简介

首先在这里推荐一本书籍《编码:隐匿在计算机软硬件背后的语言》,这本书深入浅出地介绍了计算机底层相关的诸多内容。

我们知道在计算机中只能存储二进制数据,那该怎么存储字符串呢?我们可以建立字符与二进制数据的映射关系 ,建立这个关系最起码要搞清楚两件事:

  1. 要把哪些字符映射称二进制数据?(也就是界定清楚字符范围)
  2. 怎么映射?

我们将一个字符映射成一个二进制数据的过程叫做编码

二进制数据映射成一个字符的过程叫做解码

人们抽象出一个字符集的概念来描述某个字符范围的编码规则,比如说现在我自定义一个名叫Eneru的字符集,它包含的字符范围和编码规则如下:

  • 包含字符‘A’、‘B’、‘C’、‘D’

  • 编码规则如下:

    采用1个字节编码一个字符的形式,字符和字节的映射关系如下:

    ‘A’ -> 00000001(十六进制:0x01)

    ‘B’ -> 00000010(十六进制:0x02)

    ‘C’ -> 00000011(十六进制:0x03)

    ‘D’ -> 00000100(十六进制:0x04)

有了Eneru字符集,就可以使用二进制来表示一些字符串了:

‘AD’ -> 0000000100000100(十六进制:0x0104)

‘DE’ -> 无法表示,该字符集不包含字符’E’

比较规则简介

在确定了Eneru字符集表示字符的范围和编码规则之后,怎么比较两个字符的大小呢?

最容易想到的是直接比较这两个字符对应的二进制编码的大小,比如’A’的编码0x01,‘B’的编码0x02,所以’A’小于’B’。这种简单的比较规则也可以称为二进制比较规则(binary collation)

二进制比较规则是简单的,但是有时候并不合符实际需求,比如在很多场合对于英文字符我们不区分大小写,也就是说’a’和’A’是相等的,在这种场合下就不能简单粗暴地使用二进制比较规则了,这时候可以这样指定规则:

  1. 将两个大小写不同的字符全都转换成大写或者小写
  2. 再比较这两个字符对应的二进制数据(比如比较’AB’和’AC’,先比较第一位’A’,发现是相等的;比较下一位发现B小于C,那么’AB’小于’AC’。

这是一种稍微复杂一点点的比较规则,但是实际生活中的字符不止英文字符一种,比如我们的汉字有几万之多,对于某一种字符集来说,比较两个字符大小的规则可以制定出很多种,即同一种字符集可以有多种比较规则。下面介绍一些常见的字符集和编码规则。

ASCII(字符集)

ASCII( American Standard Code for InformationInterchange,美国信息交换标准代码)是基于拉丁字母的⼀套电脑编码系统,主要⽤于显⽰现代英语和其他西欧语⾔

使⽤7 位⼆进制数,共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所以可以使用1个字节来进行编码。

32~126(共95 个)是字符(32 是空格) , 其中48~57 为0 到9⼗个阿拉伯数字。

65~90 为26 个⼤写英⽂字母(A -> 65), 97~122 号为26 个⼩写英⽂字母(a -> 97), 其余为⼀些标点符号、运算符号等。

Unicode(字符集)

ASCII 码,美国人用倒是没啥问题了,他们用到的字符几乎都包括了,但是世界上不只有美国程序员啊,所以需要一种更加全面的字符集。

Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得计算机可以用更为简单的方式来呈现和处理文字。

Unicode 发展由非营利机构统一码联盟负责,该机构致力于让Unicode 方案取代既有的字符编码方案。因为既有的方案往往空间非常有限,亦不适用于多语环境。

Unicode 可以表示中文。

UTF-8(编码规则)

有了Unicode 为啥还需要UTF-8?

广义的Unicode 是一个标准,定义了一个字符集以及一系列的编码规则(前文说到了,同一种字符集可以有多种比较规则),即Unicode 字符集和UTF-8、UTF-16、UTF-32 等等编码规则。

Unicode 是字符集,UTF-8 是编码规则。

Unicode 虽然统一了全世界字符的二进制编码,但没有规定如何存储。

如果Unicode 统一规定,每个符号就要用三个或四个字节表示,因为字符太多,只能用这么多字节才能表示完全。

一旦这么规定,那么每个英文字母前都必然有二到三个字节是0,因为所有英文字母在ASCII 中都有,都可以用一个字节表示,剩余字节位置就要补充0。

如果这样,文本文件的大小会因此大出二三倍,这对于存储来说是极大的浪费。因此出现了Unicode 的多种存储方式。

UTF-8 就是Unicode 的一个使用方式,通过他的英文名Unicode Tranformation Format 就可以知道。

UTF-8 使用可变长度字节来储存Unicode 字符,例如ASCII 字母继续使用1 字节储存,重音文字、希腊字母或西里尔字母等使用2 字节来储存,而常用的汉字就要使用3 字节,辅助平面字符则使用4 字节。

一般情况下,同一个地区只会出现一种文字类型,比如中文地区一般很少出现韩文,日文等。所以使用这种编码方式可以大大节省空间。比如纯英文网站就要比纯中文网站占用的存储小一些。

UTF8、UTF16、UTF32 的区别

前文说到了,同一种字符集可以有多种比较规则

Unicode 是字符集,UTF-8、UTF-16、UTF-32都是编码规则。

UTF-8 使用一至四个字节(可变长度字节)为每个字符编码,其中大部分汉字采用三个字节编码,少量不常用汉字采用四个字节编码。因为UTF-8 是可变长度的编码方式,相对于Unicode编码可以减少存储占用的空间,所以被广泛使用。

UTF-16 使用二或四个字节为每个字符编码,其中大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。UTF-16 编码有大尾序和小尾序之别,即UTF-16BE和UTF-16LE,在编码前会放置一个U+FEFF 或U+FFFE(UTF-16BE 以FEFF代表,UTF-16LE 以FFFE 代表),其中U+FEFF 字符在Unicode 中代表的意义是ZERO WIDTH NO-BREAK SPACE,顾名思义,它是个没有宽度也没有断字的空白。

UTF-32 使用四个字节为每个字符编码,使得UTF-32 占用空间通常会是其它编码的二到四倍。UTF-32 与UTF-16 一样有大尾序和小尾序之别,编码前会放置U+0000FEFF 或U+0000FFFE 以区分。

平常使用UTF-8比较常见,16和32比较少见。

GBK(编码规则)

有了UTF8 为什么还需要GBK?

其实UTF8 确实已经是国际通用的字符编码了,但是这种字符标准毕竟是外国定的,而国内也有类似的标准指定组织,也需要制定一套国内通用的标准,于是GBK 就诞生了。

GBK、GB2312、GB18030 之间的区别

三者都是支持中文字符的编码方式,最常用的是GBK。

以下内容来自CSDN,介绍的比较详细。

GB2312(1980 年):16 位字符集,收录有6763 个简体汉字,682 个符号,共7445 个字符; 优点:适用于简体中文环境,属于中国国家标准,通行于大陆,新加坡等地也使用此编码; 缺点:不兼容繁体中文,其汉字集合过少。

GBK(1995 年):16 位字符集,收录有21003 个汉字,883 个符号,共21886 个字符; 优点:适用于简繁中文共存的环境,为简体Windows 所使用(代码页cp936),向下完全兼容gb2312,向上支持ISO-10646 国际标准;所有字符都可以一对一映射到unicode2.0 上; 缺点:不属于官方标准,和big5 之间需要转换;很多搜索引擎都不能很好地支持GBK 汉字。

GB18030(2000 年):32 位字符集;收录了27484 个汉字,同时收录了藏文、蒙文、维吾尔文等主要的少数民族文字。优点:可以收录所有你能想到的文字和符号,属于中国最新的国家标准; 缺点:目前支持它的软件较少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值