ASCII、GB2312、Unicode和UTF-8

ASCII

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

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码(全称是“美国信息交换标准码”,American Standard Code for Information Interchange),一直沿用至今。

ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0

但这仅适用于英文字母、数字和一部分符号,世界上还有许多语言的字符需要能够被计算机系统处理,这样就需要一个比ASCII大得多的字符集囊括这些字符。

Unicode 就是用来解决这些问题的。

GB2312

GB2312 编码,就是在 ASCII 编码的基础上进行扩充的,它规定如下:

ASCII 的字符完整地包含在GB2312里,编码不变,仍然是以0开头,用一个字节来表示一个字符;对于ASCII没有的字符,就用1开头来区分,用两个字节合起来表示一个字符。

这样,在解码的时候,遇到字节是以0开头的,就知道这一个字节就表示了一个字符;遇到字节是以1开头的,就知道要加上下一个字节合起来表示一个字符。这样就在 GB2312 中既把ASCII的字符包含了进来,又能将它们区分出来,能达到兼容的效果了

GBK 即汉字内码扩展规范,其中 K 为汉语拼音扩展中扩字的声母。共收入 21886 个汉字和图形符号。

Unicode

这是全世界最大的字符集,相对于ASCII码,Unicode大大扩展了编码位数到16 - 32位,意味着它理论上最多可以容纳 2 32 ≈ 42 亿 2^{32}≈42亿 23242亿 个字符。Unicode包含了各种字母、中日韩文字、emoji等几乎所有语言和领域的符号,如汉字“我”对应的Unicode是01100010 00010001,写成16进制就是6211。现在互联网上传递、展示所使用的编码基本都是Unicode。它的最低7位与ASCII码是完全兼容的,即如果用16位Unicode来表示大写字母A,就会写成00000000 01000001。

Unicode 的问题

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

  1. 怎么才能知道一个字节表示一个符号,而不是三个字节表示
  2. 如果统一用三个字节表示一个符号,那么英文字符必然存在浪费

UTF-8

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 码。

下表总结了编码规则

Unicode符号范围UTF-8编码方式
(十六进制)(二进制)
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

总结

  1. ANSI:文件的编码就是两个字节D1 CF,这正是的 GB2312 编码,这也暗示 GB2312 是采用大头方式存储的。
  2. Unicode:编码是四个字节FF FE 25 4E,其中FF FE表明是小头方式存储,真正的编码是4E 25
  3. Unicode big endian:编码是四个字节FE FF 4E 25,其中FE FF表明是大头方式存储。
  4. UTF-8:编码是六个字节EF BB BF E4 B8 A5,前三个字节EF BB BF表示这是UTF-8编码,后三个E4B8A5就是的具体编码,它的存储顺序与编码顺序是一致的。

**简单来说:**Unicode、GBK和Big5码等就是编码的值(也就是术语“字符集”),而UTF-8、UTF-16、UTF32之类就是这个值的表现形式(即术语“编码格式”)。

**另外:**Unicode、GBK和Big5码等字符集是不兼容的,同一个汉字在这三个字符集里的码值是完全不一样的。如"汉"的Unicode值与gbk就是不一样的,假设Unicode为a040,GBK为b030。以UTF-8为例,UTF-8码完全只针对Unicode来组织的,如果GBK要转UTF-8必须先转Unicode码,再转UTF-8就OK了。

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

  1. GBK、GB2312 --先转–> Unicode --再转–> UTF8
  2. UTF8 --先转–> Unicode --再转–> GBK、GB2312

参考文章

  1. 字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8 - 知乎 (zhihu.com)
  2. ASCII、Unicode、UTF-8、GBK的区别与联系_ascii unicode utf-8 gbk区别-CSDN博客
  3. 字符编码笔记:ASCII,Unicode 和 UTF-8 - 阮一峰的网络日志 (ruanyifeng.com)
  4. 【编码】彻底弄懂ASCII、Unicode、UTF-8之间的关系 - 大唐西域都护 - 博客园 (cnblogs.com)
  5. 一文看懂字符编码 - Unicode、UTF8、GBK、GB2312、ANSI和ASCII - 兔子先生wt - 博客园 (cnblogs.com)
  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值