字符编码做了什么
因为计算机只能直接存储01两种状态,而现实中会用到非常多的符号,所以需要把用到的符号和一组01状态进行一一映射。字符编码就是实现这种映射。
所有的工作开始前,需要知道文字符号的范围,在范围内的文字符号构成了一个集合,这个集合称为字符表(Character repertoire)。
接下来,需要给字符表里面的每一个字符指定一个数字(正整数),也就是需要从字符表映射到另外一个集合,这个集合就是就是编码字符集(CCS:Coded Character Set),实现这个映射关系的是纯粹数学领域的知识。到这一步,每一个想要编码的字符会在字符表中找到,还会找到一个数字与之对应,这个数字称为对应字符的码位(code point)。
然后,还需要把编码字符集里面的内容一一转换为确定长度的比特序列,这个对应关系被称为字符编码表(CEF:Character Encoding Form)。这一步实现了码位到码单元(code unit)的转换。码单元就是若干个字节序列。到这一步,字符编码就完成了。
然而还有工作没有做完。这些码单元序列如何存储传递是另外一个环节要做的,称为字符编码方案(CES:Character Encoding Scheme),本文不表。
小结
- 字符编码就是让字符和一串计算机bit和一个字符建立一一对应关系的方法
- 编码首先要确定字符范围,范围内的字符构成字符表
- 接下来需要确定每一个字符在字符表中的位置,每一个字符得到一个与其对应的唯一编号称为码位
- 把每一个字符的码位转换为一串bit就构成了字符编码表
- 最后就得到了字符和字符编码表中内容的一一对应关系,字符编码完成
一些背景知识
- 计算机并不是按照bit为最小单位处理数据,而是以byte(8个bit)为最小单位
- 字符编码也受到这个限制,所以字符编码一开始着手就是以byte(字节)为最小单位
- 后文提到的
0x
和0b
是javascript语言的16进制和2进制数字表示方法
接下来说说各种编码规范的情况,为了阅读后面的内容,请牢记上面加粗的概念。
ASCII
ASCII(American Standard Code for Information Interchange),是基于英语的编码,覆盖了英语的字符和一些其他符号,总共有128个字符。
对于ASCII,它的字符表绝大都是天然形成的,包括英文的字母、数字和标点等,还添加了一系列有特殊约定含义的特殊符号,也就是控制符号。
字符编码的后面两个步骤在这里非常的简单,因为决定了符号的顺序就决定了后两者。
特点
- 字符编码表中都是单字节,最高一位是0(并未占满一个字节)。
- 其中前32位都是控制符号,这点很重要,后面会再提到。
- 数字排列在大写字母之前。
- 大写字母排列在小写字母之前。
整体码位
码位起 | 码位止 |
---|---|
0x0(0d0) | 0x7F(0b0111 1111) |
控制字符码位
码位起 | 码位止 |
---|---|
0x0(0d0) | 0x1F(0b0001 1111) |
小结
- 一个字节可以存储256种状态,ASCII码的字符表只有128个长度,所以在一个字节内还有空闲区域
- 因为ASCII码的字节高位是0,这也是判断一个字节内容的重要标记
- 因为ASCII码是现代计算机的基础,所以这个编码方式需要被后面出现的各种编码规则兼容
IOS-8859
IOS-8859是一系列规范的统称,主要用来解决拼音文字的编码,不同国家地区有对应的子规范,最著名的就是处理法德两国文字的IOS-8859-1编码规范。
IOS-8859兼容ASCII,扩展了字符表但是字符编码表没有超过一个字节的容量。增加了128个字符,增加的前32个字符是固定的控制字符,之后的是子规范中定义的字符。
码位说明
码位起 | 码位止 | 内容 | 说明 |
---|---|---|---|
0x00(0b0000 0000) | 0xFF(0b1111 1111) | 整体码位范围 | |
0x80(0b0000 0000) | 0xEF(0b0111 1111) | ASCII码区 | |
0x80(0b1000 0000) | 0x9F(0b1001 1111) | 控制符 | |
0xA0(0b1010 0000) | 不换行空格 | 对应ASCII的空格符号0x20(0b0010 0000) | |
0xA1(0b1010 0001) | 0xFF(0b1111 1111) | 其它字符 | 相同码位在不同字符集有不同内容 |
特点
- 编码出来的内容仍然是单字节。
- 在160之后的码位,会在不同的子规范下分配给不同的字符。
- 安全。因为它的字符编码表覆盖了一个字节范围内的所有组合。其它编码的内容采用它来解码不会出错。
小结
在一个字节的容量内,ASCII占用了前半部分,满足了需求;IOS-8859占用了后半部分,满足了许多拼音文字的需求。
很显然,对于字符个数超过一个字节的语言,这种编码方式就难以为继了。