字符集和编码
# 关键词
- 字符集
- 编码
- ASCII
- Unicode
- UTF-8、UTF-16...
- GBK
# 字符集
让我们思考这样一个问题:我们使用的文字,符号,在计算机中是如何表示的呢?
首先字符是一种抽象的数据,我们需要将其转化为方便计算、存储的数据。一种简单的方式是建立一个有序列表,用一个序号来表示一个字符。
假设我们使用一个超级简单的语言,只有8个字符:
序号 | 字符 |
---|---|
0 | A |
1 | B |
2 | C |
3 | D |
4 | 0 |
5 | 1 |
6 | , |
7 | . |
像上面的表,我们约定了一个规则,用0-7表示了所需的字符。这样我们就定义出了一个字符集
(Charset)。
字符集是纯粹的数学概念。它的作用是完成数到字符的映射。例如,当我提到数字3
,根据约定,它将代表字符D
。
在计算机诞生之初,美国的ANSI率先定义了 ASCII
(发音 ass-key)字符集。它定义了英文大写、小写字母、数字、符号和特殊的控制字符共128个。
(具体我后面再补)
提示
ASCII: American Standard Code for Information Interchange,美国信息交换标准码
利用 ASCII 的编码可以用一个字节的7个位表示一个字符。所以在 ASCII 的标准编码下,一个字符需要占据一个字节的存储空间。
不过人们很快发现 ASCII 规定的128个字符不够用了。例如欧洲各国一些变音字符。于是他们就决定,将每个字节闲置的一个位利用上,将 ASCII 的范围扩展到 0-255。如此范围扩大了一倍,每个字符仍然占用一个字节。
新的问题出现了,不同的国家出现了不同的 ASCII 扩展,导致相互不兼容。随着计算机的普及,一些语言的文字十分复杂(例如汉字)。各国各地区都出现了自己的字符集和编码,但代价是互相无法理解。人们意识到已有的字符集已经完全满足不了全世界的需求了。
这个时候,Unicode出现了。Unicode的范围非常广。截至目前,Unicode一共定义了 111 4112 个字符(或码位)。包括了目前世界已知绝大多数语言文字,甚至是emoji(这是后话)。现代的计算机都有Unicode的支持。为了适配原有标准,Unicode保留了ASCII的规则。
提示
Unicode: 统一码
至此,人类语言文字的计算机表示就此成型。
# 编码
定义完成了,接下来的就是优化。Unicode表示的范围如此之广,按照常规的思路,必然需要消耗大量的空间来存储。
一般的思路是,用一个定长的范围来表示一个字符。比如ASCII的字符少,只需要一个字节。但Unicode字符极其多,需要4个字节。
例如,“汉字”的unicode值分别是 27721 和 23383。定长表示可以存储为:
00000000 00000000 01101100 01001101 | 00000000 00000000 01011011 01010111
这就是UTF-32编码。
提示
UTF:Unicode Transfer Format,统一码传输格式。
32
指一个字符占用32位。
这种编码下,可以发现出现了大量的00000000
。因为大部分的Unicode字符平常是用不到的,却耗费了大量的空间去存储。比如同一份文件,ASCII存储100kb,换用UTF-32存储直接变成了400kb。这当然是无法忍受的。
于是,更加简洁的Unicode编码方案诞生了。
# UTF-8
UTF-8是当代使用最广泛的Unicode编码,没有之一。我有点懒,明天再写。
优点:兼容ASCII,简短。
# 区别
前面提到了,字符集是纯粹的数学概念。而编码是计算机概念,提供一种表示方式,将序号(码点)供给计算机使用。
可以说,编码是字符集的一种实现方式。
Unicode表我过两天再补awa
Unicode趣味知识:
im so laZzzy