浅析 Unicode 和 UTF-8 的关系

近来无事,不经意想起了大学老师留下的一个问题。Unicode1 和 UTF-82 到底是什么关系?要搞清楚这个问题,先要从 ASCII3 码开始说起。

计算机内部所有的信息的存储和传输都是通过二进制的形式进行的,计算机只能够识别二进制的值,每个二进制位有 0 或者 1 两种状态。如果此时拥有 8 个二进制位,就可以组合出 28 = 256 个不同的二进制数,也就代表 256 种不同的状态,这也被称之为一个字节(Byte)。

这 256 种不同的状态可以表示 256 种不同的字符,比如大小写字母、数字、标点符号等。ASCII 码就是使用 8 个二进制位来表示 256 个字符,其中 0~127 用来表示标准 ASCII 码,128~255 用来表示扩展 ASCII 码。

美国在 1963 年制定了 ASCII 码,ASCII 码使用 7 位二进制数来表示 128 个字符,包括大小写字母、数字、标点符号和一些控制字符。ASCII 码的使用非常广泛,但是只能表示英文字符,对于其他语言的字符就无能为力了。

为了使计算机能够处理其他语言的字符,Unicode 应运而生。Unicode 是一个非常庞大的字符集,它为每个字符分配一个唯一的数字,这个数字就是字符的码点。Unicode 的码点是用十六进制表示的,比如大写字母 A 的码点是 U+0041。Unicode 的码点是从 U+0000U+10FFFF,总共有 1,114,112 个码点。

Unicode 只是一个字符集,它只规定了字符的码点,但是没有规定这个码点应该如何存储。UTF-8 就是 Unicode 的一种存储实现方式。UTF-8 使用 1~4 个字节来表示一个字符,根据不同的码点,UTF-8 会选择不同长度的字节来存储。UTF-8 的编码规则如下:

Unicode 符号范围 (Hex)UTF-8 编码方式 (Bin)
0000 0000-0000 007F0xxxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Unicode 和 UTF-8 的关系就是这样,Unicode 是一个字符集,UTF-8 是 Unicode 的一种存储实现方式。换言之,UTF-8 是 Unicode 的一种编码方式。

例如,字符 A 的 Unicode 码点是 U+0041,它的 UTF-8 编码是 01000001。字符 的 Unicode 码点是 U+4E2D,它的 UTF-8 编码是 11100100 10111001 10010101。如此一来就可以通过 1 个字节来保存一个英文字符,用 3 个字节来保存一个中文汉字了。


  1. Unicode 是一个字符集,它为每个字符分配一个唯一的码点。 ↩︎

  2. UTF-8 是 Unicode 的一种存储实现方式,它使用 1~4 个字节来表示一个字符。 ↩︎

  3. ASCII 码使用 7 位二进制数来表示 128 个字符,包括大小写字母、数字、标点符号和一些控制字符。 ↩︎