计算机系统解密:从理解计算机到编写高效代码
上QQ阅读APP看书,第一时间看更新

1.11 用字符表示数字

UTF-8用数字来表示由代表字符的位组成的数字。但是我们还没有完成!现在,我们要用字符来表示其中的一些数字。在计算机与计算机互相通信的早期,人们希望在计算机之间发送的不仅仅是文字,还希望发送二进制数据。但在计算机间发送二进制数据并不简单,因为许多ASCII值都是为控制字符保留的,而且不同系统之间的处理方式不一致。此外,有些系统只支持7位字符的传输。

1.11.1 可打印字符引用编码

可打印字符引用编码也称为QP编码,是一种允许将8位数据通过只支持7位数据的路径进行通信的编码,常用于电子邮件附件。这种编码允许任何8位的字节值由3个字符表示:字符“=”后跟一对十六进制数字(1个数字对应1个半字节)。当然,这样做的过程中,“=”具有特殊含义,因此必须用“=3D”代表它,它的值见表1-11。

可打印字符引用编码有一些额外的规则。如果制表符和空格字符出现在行尾,必须分别用“=09”和“=20”表示。编码后数据行的长度不能超过76个字符。在行末的“=”是一个软换行符,当接收方解码数据时会删除。

1.11.2 Base64编码

虽然可打印字符引用编码可以使用,但因为需要三个字符来代表一个字节,它的效率并不高。Base64编码更有效率,而效率在计算机之间的通信速度比现在慢得多的时候非常重要。Base64编码将3字节的数据打包分配给4个字符。这3字节的24位数据被分割成4个6位的块,每个块分配一个打印字符,如表1-13所示。

表1-13 Base64字符编码

图1-17展示了如何将字节0、1、2编码为AAEC。

图1-17 Base64编码

图1-17所示的编码以3字节为一组,将其转换为4个字符。但不能保证数据的长度是3字节的倍数,因而可以通过填充字符来确保数据的长度是3字节的倍数;如果末尾只有2字节,则会在末尾添加一个“=”,如果末尾只有1字节,则会在末尾添加“==”。

这种编码也常用于电子邮件附件。

1.11.3 URL编码

在上文中可以看到,可打印字符引用编码赋予了“=”字符特殊的权力,编码中也包含了表示“=”但没有特殊的功能的机制。网页URL使用了几乎同一种模式。

如果你曾经检查过网页的URL,可能已经注意到像%26和%2F这样的字符序列。这些字符之所以存在是因为它们在URL的上下文中具有特殊含义。但有时我们需要用这些字符作为字面值,换句话说,就是不含特殊的意义。

上一节提到,字符被表示为一个8位数据块的序列。每个数据块可以用两个十六进制的字符来表示,如图1-16所示。URL编码,也称为百分制编码,用%后面跟着其十六进制表示的形式替换字符。

例如,正斜线字符(/)在URL中有特殊的含义。它的ASCII值为47,也就是十六进制中的2F。如果我们需要使用URL中的“/”,而不想触发其特殊含义,可以用%2F代替“/”。(因为我们刚刚给%字符赋予了特殊含义,如果想在字面上表示%,需要用%25代替%。)