字符集的解析

计算器编码

Ascii

计算机内部,所有信息都是二进制进行展示,每个二进制为有0与1的状态,一位代表1bit,计算机中最小的存储单位为byte(字节),一个字节由八位组成,总共可以展示256(2^8)种状态。计算器在美国发源,制定了一套字符编码与二进制对应的关系,8位第一位取0,后7位变换对应字符总共128种状态,如1000001(65)代表字母a,此时二进制与符号的对应关系位Ascii码。

Extend Ascii

随着计算机的快速发展,计算机的使用不再局限于美国,发展到欧俄这些国家,Ascii的的的规定不再满足这些,欧美国家就将第一位开放出来,扩充了128个满足拉丁语系的使用。

其他编码

计算机的快速发展,全世界都在使用Ascii也不能满足一些地区的文字符号使用,类似于中国有7万多个汉字符号,这些国家就采用两个字节的扩充来满足文字的多样性的表示。如Gb2312则是中国的汉字与二进制的对照关系。

Unicode

在计算机进入中国大陆的相同时期,计算机也迅速发展进入了世界各个国家。 特别是对于亚洲国家而言,每个国家都有自己的文字,于是每个国家或地区都像中国大陆这样去制定了自己的编码标准,以便能在计算机上正确显示自己国家的符号。 但带来的结果就是国家之间谁也不懂别人的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海里,都使用了不同的编码体系。 于是,世界相关组织意识到了这个问题,并开始尝试制定统一的编码标准,以便能够收纳世界所有国家的文字符号。 在前期有两个尝试这一工作的组织:

国际标准化组织(ISO)
统一码联盟
  简单理解:Unicode,是一张表,它为世界上所有文字字符都分配了一个唯一编号(也称为码点,如字符A,它的编号是:十进制数字 41)。而UTF-8,UTF-16呢,会以Unicode这个编号为基础,通过一个规定算法,计算出他们各自的编码值。

这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

UTF-8

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8 的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表总结了编码规则,字母x表示可用编码的位。
跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字严为例,演示如何实现 UTF-8 编码。

严的 Unicode 是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5。

go

Unicode码点对应Go语言的rune整数类型,rune又是int32等价类型,4个字节能容纳Unicode码点0~10FFFF的3个字节。

我们可以将一个符文序列表示为一个int32序列。这种编码方式叫UTF-32或UCS-4,每个Unicode码点都使用对应数值的32bit来表示,是等长编码。这种方式比较简单统一,但它会浪费很多存储空间,因为大部分计算机可读的文本是ASCII字符,本来每个ASCII字符只需要8bit或1字节就可以表示。而且即使是常用的字符也远少于65536个。golang中string底层是通过byte数组实现的,内置名字空间的len()函数作用于字符串时返回字符串占用的字节数。golang默认编码是UTF-8,指golang的数据区、堆栈存储字符串时使用UTF-8编码存储,中文字符的Unicode码是2个字节,对应UTF-8编码是3个字节,byte类型与rune类型都用来表示字符类型:byte等同于int8,常用来处理ascii字符;rune等同于int32,常用来处理uniocde或utf-8字符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值