字符编码简介

2021-05-20 10:28:05 浏览数 (1)

所谓编码(Encoding),是信息从一种形式或格式转换为另一种形式的过程。例如“山雪河冰野萧瑟,青是烽烟白人骨”中的“烽烟”,就是古代将敌人入侵的信息,转换为“烽烟”得以快速传递——古老的长途通讯方式之一。看到“烽烟”的将士们正确理解其含义——没有理解为烧柴做饭,即编码的逆过程,称为解码(Decoding)。

在互联网广泛使用之前,电报曾是一种重要的长途通讯方式,它能将字符转化为电信号,例如著名的摩尔斯电码(Morse code)中用点(·)和划(-)对字符编码,如表4-1-1所示,即为对英文字母的编码。点和划可以通过电键敲击对应为不同的电信号,从而将字符组成的文本内容通过有线或无线的电磁波发送到远端。远端接收到此信号之后,通过解码还原出文本内容。

表4-1-1 英文字母和摩尔斯电码

字符

代码

字符

代码

字符

代码

字符

代码

字符

代码

字符

代码

字符

代码

A

·-

B

-···

C

-·-·

D

-··

E

·

F

··-·

G

--·

H

····

I

··

J

·---

K

-·-

L

·-··

M

--

N

O

---

P

·--·

Q

--·-

R

·-·

S

···

T

-

U

··-

V

···-

W

·--

X

-··-

Y

-·--

Z

--··

(表4-1-1源自《维基百科》的“摩尔斯电码”词条,https://zh.wikipedia.org/wiki/摩尔斯电码)

据不太可靠的消息,泰坦尼克号首航遇险时,曾通过电报发出了如今我们熟知的求救信号“SOS”,其摩尔斯电码是“···---···”,听起来就是“滴滴滴”(三短音)、“答答答”(三长音)、“滴滴滴”(三短音),辨识度非常高,而且容易记忆和操作,甚至于普通民众利用一些器物敲击也可以传达此信息,故被定为国际通用的求救信号(1991年9月22日,国际海事机关决定从1992年二月开始废除SOS信号,改用新的国际海事卫星电子通信设备,只要一按电钮,所有关于事故发生及位置数据将自动地通报救援机关。这比采用莫尔斯电信设备要快速、准确、方便得多)。很可惜,当时在泰坦尼克号附近的一艘名为“加州人号”邮轮的电报员关了电报机睡觉去了,该求救信号第二天早上才被收到。

可以说,电报是一种早期的数字化通信方式。尽管摩尔斯电码的方案不能直接搬用到计算机上,但让计算机“认识”字符的原理与之近似,区别在于要将字符转换为“二进制的数字”形式,从而建立起字符与二进制的位(bit)之间的对应关系,此即为字符编码(Character Encoding)。

1960年代,美国发布了“美国信息交换标准代码”(American Standard Code for Information Interchange,简写ASCII)。在ASCII中,主要规定了英语字符在计算机中的编码,1986年发布的最新版一共规定了128个字符的编码。

利用 Python 中的内置函数 ord() 可以得到ASCII中某个字符编码的十进制表示(在 Python 交互模式中调试)。

代码语言:javascript复制
>>> ord("A")
65

这个十进制数字对应的二进制数字可以用 bin() 函数得到(参阅第3章3.4.1节)。

代码语言:javascript复制
>>> bin(65)
'0b1000001'

十进制整数 65 对应的二进制数是 1000001 。只不过在ASCII中,每个字符的编码只占用了一个字节(见4.1.3节)的后面

7

位,最前面的一位统一规定为 0,即为 01000001

ASCII对于英语而言已经足够了,但仅此而已,英语以外的语言怎么办?于是有了针对其他语言的编码,例如ISO 8859(全称ISO/IEC 8859,是国际标准化组织(ISO)及国际电工委员会(IEC)联合制定的一系列8位字符集的标准)针对希腊语提出了ISO 8859-7编码字符集。但是,尚有很多语言没有与ISO 8859兼容或它没有涵盖其他语言的字符,于是在显示上经常出现所谓的“乱码”,例如用KOI-8对俄文单词“кракозбббры”进行编码,然后使用ISO 8859-1解码,将看到“ËÒÁËÏÚÒÙ”。

随着互联网的发展,不同语言之间的交流更加密切,迫切需要涵盖所有语言字符的编码方案。于是,20世纪80年代末出现了两个相互独立的方案:一个是 ISO 10646,另一个是Unicode。这两个项目有共同的目标:用一个涵盖所有正在广泛使用的语言的通用编码替换数百个相互冲突的字符编码。并且这两个项目在1991年合并,统一为Unicode字符集。这就是现在被广泛采用的字符集。

Unicode(译为:统一码)是目前计算机科学领域的编码标准,它涵盖了世界上绝大部分的文字系统,至今仍在不断更新,当前的最新版是2020年3月公布的13.0.0,已经收录了超过13万个字符。Unicode 包括视觉上的字形、编码方法、标准的字符编码、字符特性(大小写字母)。

Unicode 使用16位的编码空间,每个字符占用

2

个字节,这样理论上一共最多可以表示

2^{16}

(即

65536

)个字符——每个汉字是一个字符,常用汉字在3000~4000个,用汉字来衡量,Unicode 基本满足需要。也不用担心这种编码方式无法涵盖其他语言或者符号,因为 Unicode 还保留了大量空间以作为将来扩展,并且未来的版本会涵盖 UCS-4(通用字符集的一个版本)的所有字符,届时理论上能表示

2^{31}

个字符,完全可以涵盖所有语言中的符号了。

当一个字符的 Unicode 编码确定之后,在实际传输过程中,由于不同系统的设计差异,并且要节省空间,于是对 Unicode 编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。例如字符 A ,按照 ASCII 只要编码为 1000001 (7位)即可,若使用 Unicode 编码需要用两个字节,第一个字节全是 0 ,这显然造成了比较大的浪费,所以需要“变长编码”,即 ASCII 字符用一个字节(仍用7位编码,首位补 0),其他字符用两个、三个,乃至四个字节。这种 Unicode 的实现方式就是当前普遍采用的 UTF-8(8-bit Unicode Transformation Format),类似地还有 UTF-16 和 UTF-32 。截止到2019年11月, 在所有网页中,UTF-8编码应用率高达94.3%(其中一些仅是ASCII编码,因为它是UTF-8的子集),而在排名最高的1000个网页中占96%(参考【维基百科】的“UTF-8”词条)

注: 此文是正在编写的一本书的草稿中的一节内容。

0 人点赞