目录
ACSII 码
Extended ACSII 码
Unicode
UTF-8/UTF-16/UTF-32
Base64
前序
在具体介绍各种字符编码(character encoding)前,首先得搞懂一个再简单不过的问题:
为什么要进行字符编码?
答案很简单:因为计算机只认识二进制0和1,所以要想将信息存储在计算机内,都需要转换为二进制格式。所以我们这里所说的“字符编码”其实具体指的是“如何将字符用二进制来表示”。
我们听说过的字符编码方式有哪些呢?这些字符编码方式是怎么演化而来的呢?每种编码方式对字符又是怎么进行编码的呢?
今天我们就一起来共同探索下~~
字符编码方式
1. ASCII 码
这个编码相信大家肯定熟悉,这是大学里计算机课程的必讲内容,值得一提的是这种编码方案是由美国佬提出的。为什么值得一提呢?因为美国佬说的是英语,他们语言中只有128个字符,所以对于他们来说只要解决如何将这128个字符用不同的二进制串表示就可以了。
由于2^7刚好等于128,所以要表示这128个字符只需要7 个比特位即可。但由于计算机中信息存储是以字节为切割单位,最小的一个字节是8个比特位,所以美国佬就想到了这样一种编码方案:只用1个字节的后7 个比特位,最前面的1位统一为0来表示他们的128个字符,显然有1个比特位是浪费的。
ASCII 码范围:00000000-011111111(除32个控制字符外,其余为可打印字符)
ASCII 码存在什么问题?
1.1 ASCII 码存在问题
对于美国这类英语国家(只需要128个字符),ASCII 码确实足够了。但是对于其他非英语国家如法国等超过128字符的欧洲国家,ASCII 码显然不能对所有字符进行编码。怎么办呢?这时欧洲佬想起了ASCII 码编码方案中最高比特位是空闲的,为啥不充分利用呢。于是原先用来表示ASCII 码的一个字节所有8个比特位都被用来编码,于是就有了Extended ASCII 码。
2. Extended ASCII 码
将原本空闲的最高比特位用来参与编码后,因为2^8=256,所以可表示的字符增加到了256个。但原来的00000000-011111111码段仍然用来表示之前ASCII码对应的128个字符。
由于 Extended ASCII 码可以表示256个字符,对于欧洲国家已经够用。但由于每个欧洲国家语言用的字母不同,导致出现了同一个编码值对应不同字母的情况。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个字符。但是不管怎样,0--127表示的字符肯定是一样的,不一样的只是128--255的这一段。
Extended ASCII 码存在什么问题?
2.1 Extended ASCII 码存在问题
这种”一个编码值不能唯一对应一个字符”的情况经常会导致解码错误而出现一堆乱码。当信息在不同的平台或者不同的编码系统中传输时,要想每一台机器都能够正确解码,那么这些机器就必须要支持各种各样的编码方式,而这一点是很难做到的。
那么如何解决这种乱码问题呢?
如果世界上的所有字符都能用唯一的码值来表示,那么乱码问题就不会出现了。于是就有了 Unicode 编码。
3. Unicode
Unicode 核心思想是什么?
3.1 Unicode 出现的意义
在 Unicode 出现之前,有各种各样的编码方案,但没有任何一种编码方案能够包含世界上的所有字符。更为糟糕的是,这些编码方案会彼此冲突,不同的编码方案用同一个码值表示不同的字符,或者同一个字符用不同的码值表示。而有了 Unicode,全世界实现了大一统,每一个字符都对应唯一的码值,信息的传输障碍消除了。
3.2 what is Unicode?
Unicode provides a unique number for every character,
no matter what the platform,
no matter what the program,
no matter what the language.
解惑一:"unique number" 指的是二进制码吗?
上面提到的 number 并不是指最终存储的二进制码,而是一串由0和1组成的数字而已,这一串数字的专业术语叫码点(code point)。
码点格式:U+xxxx
U+表示紧跟在后面的是十六进制数,这4个字节的0和1数字串就是Unicode码点。比如,中文"好"的码点是十六进制的597D:U+597D = 好
解惑二:Unicode 是一种字符编码方式吗?
答:不是!Unicode 只是规定每个字符对应的码点,但具体存储时怎么携带这些码点就涉及到了编码方式。
你能想到的实现Unicode 编码方法有哪些?
答:最容易想到的编码方法是:每个码点使用四个字节表示,字节内容一一对应码点。这种编码方法就叫做UTF-32。比如:
U+0000 = 0x0000 0000
U+597D = 0x0000 597D
3.3 Unicode 的几种编码方式
(1) UTF-32
UTF-32 这种字符编码方式有什么缺点?
特点:定长编码,字符用四个字节表示
问题:浪费现象严重,所以急需一种节省空间的编码方法,于是 UTF-8诞生了。
(2) UTF-8
UTF-8 这种字符编码方式有什么优点?
特点:变长编码,字符长度从1个字节到4个字节不等。越是常用的字符,字节越短,最前面的128个字符,只使用1个字节表示,与ASCII码完全相同。
UTF-8的编码规则很简单,只有二条:
对于单字节的字符,字节的第一位设为0,后面7位为这个字符的unicode码。因此对于英文字符,UTF-8编码和ASCII码是相同的。
对于n字节的字符(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个字符的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制 )
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
规律总结:如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
(3) UTF-16
特点:结合变长和定长的特点,每个字符用两个字节或四个字节表示。
Base64
(1) what is Base64
解惑一:Base 64 是一种字符编码方式吗?
答:Base64 不是对字符进行编码,而是对字符编码后得到的二进制串进行编码转换,所以可以作为一种简单的加密方式。
解惑二:名字中的“64”指的是什么?
答:指的是64个可打印的 ACSII 码字符:
小写字母a-z
大写字母A-Z
数字0-9
符号"+"和"/"
Base64的特点:
Base64会将所有的二进制文件,都转化为可打印的64个字符
相同的字符,若采用不同的字符编码方式,转换得到的 Base64编码值也是不同的。
(2) 编码转换方式
转换分4步:
将每三个字节作为一组,一共是24个二进制位。
将这24个二进制位分为四组,每个组有6个二进制位。
在每组前面加两个00,扩展成32个二进制位,即四个字节。
根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y
4.3 具体转换实例
举一个具体的实例,演示英语单词Man如何转成Base64编码。
参考文档: 1. 2. 3. 4. 5.