【ASCII 、Unicode、UTF-8编码关系】

参考:https://www.cnblogs.com/tsingke/p/10853936.html

为什么会出现乱码

一份文件,根据编码A的规则将文件转换为二进制存储起来。
被使用另一种编码B打开,根据编码B的规则将二进制解析。就解析出不一样的文件,甚至是乱码。

所以,要想打开一个文件,就必须提前知道它的编码方式,
或者约定,所有文件的读写都使用统一的编码。

字符编码的作用

计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出 256 种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从 0000000011111111

为了让计算机中的0、1与日常使用的符号互相识别,上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间,做了固定的一一对应。这被称为 ASCII 码,一直沿用至今。

ASCII

ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。
这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位(2^7=128),但是计算机都用字节(byte)作为一个单元,所以将最前面的一位统一规定为0,补齐8位作为 1 byte。

英语用128个符号编码就够了,但是用来表示其他语言,256个符号还是不够的。
尤其对于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。256种符号是远远不够的。

Unicode

为了实现全球统一编码。
如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。

Unicode 的问题

需要注意的是,Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字 的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题
第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机拿到一串24位(3 Byte)二进制数,怎么知道三个字节表示一个符号,而不是三个字节分别表示一个符号呢?
第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 为了兼容其他更大的字符,采用统一规定,如每个符号都用三个字节标识,那么每个英文字母的前两个字节前都补0组成24位,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

UTF-8

UTF-8 是 Unicode 的实现方式之一,是Unicode的一种存储、传输方式。对Unicode在传输、存储方面的补充。Unicode都既是字符集,也是编码方式,而UTF-8只是编码方式,并不是字符集。

或者通俗一点说,Unicode负责根据字符集映射成对应的二进制代码,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表示可用编码的位。

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 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符(兼容ASCII 码);如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节(如最后一条是4段,即4个字节,那么从开始有4个连续的1)。

GBK

GBK 包含全部中文字符,也就是说,gbk并不是出于统一编码的目的出现,仅仅是为我们汉字编码而形成之解决方案。不能做到国际通用。

gbk编码每个字符占用2个字节,而UTF-8中出现中文那就是3个字节,所以采用gbk编码的文本,在UTF-8环境下打开必然乱码。

GBK、GB2312、GB18030 等与UTF8之间都必须通过Unicode编码才能相互转换。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值