浅析 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+0000
到 U+10FFFF
,总共有 1,114,112 个码点。
Unicode 只是一个字符集,它只规定了字符的码点,但是没有规定这个码点应该如何存储。UTF-8 就是 Unicode 的一种存储实现方式。UTF-8 使用 1~4 个字节来表示一个字符,根据不同的码点,UTF-8 会选择不同长度的字节来存储。UTF-8 的编码规则如下:
Unicode 符号范围 (Hex) | UTF-8 编码方式 (Bin) |
---|---|
0000 0000-0000 007F | 0xxxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 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 个字节来保存一个中文汉字了。