0%

字符编码笔记(一)

字符编码做了什么

因为计算机只能直接存储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(字节)为最小单位
  • 后文提到的0x0b是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占用了后半部分,满足了许多拼音文字的需求。

很显然,对于字符个数超过一个字节的语言,这种编码方式就难以为继了。