字符编码常识简单介绍

一直以来都有点搞不清楚各种字符编码的区别,但又总是碰到 ASCII、Unicode、UTF-8 等字符编码术语,所以查了点资料了解了一下这几种编码的区别及原理,下面简单记录介绍一下吧。

编码原理

在计算机内部,所有信息最终都是用一个二进制的值来表示。每个二进制位有 01 两种状态,每八个二进制位(bit)组成一个字节(byte),所以很明显的,每个字节共有 2^8=256 种状态。每个状态对应一个二进制值,从 0000000011111111

ASCII 码

ASCII 码是由美国制定的一套字符编码,对英语字符和字节二进制值的对应关系做了统一的规定。

ASCII 码使用一个字节来表示一个字符,一共规定了 128 个字符的编码,这些字符只使用了单个字节中的后七个二进制位(2^7=128),第一位统一为 0

对于英语来说,ASCII 编码的 128 个字符已经足够使用,但对于其他语言来说就有点不够了。所以有一些语言将 ASCII 编码中闲置的第一位也利用了起来,充分使用单个字符的 256 种状态。但这样就造成了一个很明显的问题:同一编码在不同语言编码体系中表示的字符不同,容易造成混乱。

更进一步,对于一些象形文字发展出来的语言,比如中文,要为每一个“字”对应一个编码,单个字节的 256 种状态远远不够,必须使用多个字节来表示一个字符。比如简体中文的 GB2312 编码方式,使用两个字节表示一个字符,最多可以表示 256×256=65536 个字符。

Unicode

由于前面提到的问题,在不同的编码体系中同一个二进制数字可以被解释成不同的字符。因此,要想正常打开一个文件,就必须知道它的编码方式,否则就会出现乱码的问题。由此 Unicode 应运而生。

Unicode 是一个统一的编码集合,类似于编码界的世界语,它将世界上所有的字符都赋予的一个独一无二的编码,从而避免了字符编码混乱的问题。

需要注意的是 Unicode 只规定了字符的二进制代码,但并没有规定这个二进制码应该如何存储表示,这就引出了后文的 UTF-8 编码。

UTF-8

UTF-8 全名为 8-bit Unicode Transformation Format ,从名字就可以看出来,它其实是 Unicode 的实现方式之一。

不同于纯粹的 Unicode,UTF-8 规定了 Unicode 字符的存储方式。使用一种变长的编码方案,用 1~4 个字节表示一个字符,根据不同的字符改变字节长度,从而做到在兼顾所有字符的情况下将占用空间尽可能的减小。因此成为了互联网上使用最广的一种 Unicode 实现方式。

UTF-8 具体的编码规则如下:

  1. 对于单字节的字符,字节的第一位设为 0 ,后七位为这个字符的 Unicode 码,因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
  2. 对于 n 个字节的字符(1<n<=4),第一个字节的前 n 位都设为 1 ,第 n+1 位设为 0 ,后面字节的前两位一律设为 10 。剩下没有提及的二进制位全部为这个字符的 Unicode 码。

在知道了编码方式的条件下,解读 UTF-8 编码的字符串也就很简单了:如果一个字节第一位是 0 ,这这个字节单独就表示一个字符,取出 Unicode 码对应即可;如果第一位是 1 ,则连续有多少个 1 ,就表示当前字符占用多少字节,根据上面编码规则就可以得到该字符对应的 Unicode 码,从而得到对应字符。