在计算机底层,比如你的名字“小明”在计算机中并不是文字形式,而是一串二进制数字,如“0110110100..”。其中这个过程叫做编码。即将文字转换成二进制的过程极为编码,而将二进制转换成文字的过程叫做解码。 ASCII, utf-8, utf-16, utf-32被称作字符集。
ASCII码
因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),0 - 255被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。
ASCII码不支持中文,所以中国制定了GB2312来把中文加进去。日文和韩文等其他语言也有同样的问题,为了统一所有文字的编码,诞生了Unicode.
Unicode
Unicode编码定义了这个世界上几乎所有字符(就是你眼睛看的字符比如ABC,汉字等)的数字表示,而且Unicode还兼容了很多老版本的编码规范,例如刚刚讲过的 ASCII码。
我们国家的每一个人都对应唯一的一个身份证号,而Unicode也为了每个字符发了一张身份证,这张“身份证”上有一串唯一的数字ID确定了这个字符。这串数字在整个计算机的世界具有唯一性,Unicode给这串数字ID起了个名字叫[码点]。很多人说的编码其实是想表达Unicode转换格式(即UTF- Unicode Transformation Formats)。这个[Unicode转换格式]的是为了解决[码点]在计算机存储方式而设计的。[码点]经过映射后得到的二进制串的转换格式单位称之为[码元](Code Unit)。[码点]就是一串二进制数,【码元】就是切分这个二进制数的方法。举个例子,如果有一个字符的码点二进制表示有n字节(n*8个二进制数),其码元为8位(1个字节),那么其拥有码元n个。
Unicode 编码 发展到今天 扩展到了 21 位,为啥扩展到21位了呢?因为一开始老美只考虑自己那26个英文字母和数字,随着越来越多的国家的语言语言编码,Unicode不得的继续扩展,目前21位已经足够使用。
UTF-32
UTF-32也就是说它的码元是32位,每32位去读一下码点,而码点是Unicode给字符的编码,前面也说了,最长才21位,因此每一个 UTF-32 值都可以直接表示对应的码点。而一个字符站4个字节太浪费空间了,所以就有了utf-8, utf-16。
编码空间
前面说了Unicode ,它是 21 位的。这 21 位提供了 1,114,112 个码点,编码空间就是对应这1,114,112 个码点。对了这里要说一下,这么多码点并不代表有这么多字符,目前大概只有10%的空间被使用了,人类社会还没创造出1,114,112 这么多的字符。编码空间被分成 17 个平面(plane),每个平面有 65,536 个字符(正好填充2个字节,16位)。0 号平面叫做「基本多文种平面」( BMP, Basic Multilingual Plane ),涵盖了几乎所有你能遇到的字符,除了 emoji(emoji位于1号平面 )。其它平面叫做补充平面,大多是空的。
UTF-16
它的码元是16位的,也就是说每16位去读一下码点,获取码点的前16位数字,直到读取完成。编码空间这里要用上了哈,BMP平面(也就是前面说的基本多文种平面)中的每一个码点都直接与一个UTF-16 的码元一一映射。由于BMP 几乎包括了所有常见字符,UTF-16 一般需要 UTF-32大约 一半的空间。至于其它平面里很少使用的码点都是用两个 16 位的码元来编码的。(UTF-16对于常见的字符使用2个字节,不常用的字符使用4个字节,大大节省了空间)。
UTF-8
UTF-8 使用一到四个字节来编码一个码点。从 0 到 127 的这些码点直接映射成 1 个字节(对于只包含这个范围字符的文本来说,这一点使得 UTF-8 和 ASCII 完全相同)。接下来的 1,920 个码点映射成 2 个字节,在 BMP 里所有剩下的码点需要 3 个字节。Unicode 的其他平面里的码点则需要 4 个字节。UTF-8 是基于 8 位的码元的。UTF-8 是基于 8 位的码元的,因此它并不需要关心字节顺序(因为字节就是8位的呀,其它UTF-16和UTF-32在不同的机器编译环境下需要考虑字节的顺序问题)。