编码:隐匿在计算机软硬件背后的语言
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1 至亲密友

你今年10岁,你最好的朋友就住在街对过。事实上,你们各自卧室的窗户正好彼此相对。每当夜幕降临,父母就如同往常一样,早早地催促你该上床睡觉了,但是你和你的朋友还想交流想法,交换见闻,分享各自的秘密,或者扯扯闲话,开开玩笑,聊聊梦想。这本无可厚非。无论怎样,渴望交流本来就是人类最主要的天性之一。

当卧室里的灯依然亮着的时候,你可以和朋友互相挥手,使用各种手势或简单的肢体语言,来表达一两个想法。但是,要表达复杂的想法可能就比较困难了。而且一旦父母宣布“关灯”,这种交流似乎也不可能继续下去。

如何交流呢?或许可以打电话?10岁小孩的房间里会有电话吗?即使有,无论电话在哪里,你们的谈话都有可能被偷听。如果你家里的电脑连接了电话线,它可能帮上忙,而且不会发出声响,但是——等等,电脑也不会在你的房间里。

你和朋友所采用的方法就是使用手电筒。众所周知,手电筒是为了让孩子们能够躲在被子下看书而发明的;在天黑后用手电筒来交流信息似乎也是理想的选择。它们当然是很安静的,并且光线是高度定向的,同时光线也不会渗漏出卧室而引起家人的疑心。

手电筒能用来交谈吗?这当然值得一试。我们在一年级的时候学习怎样在纸上写字母和单词,因此,把同样的方法运用到手电筒上似乎也是有道理的。只需要站在窗户边,用光来画出字母。对于字母“O”,打开手电筒,在空气中划一个圈,然后关掉手电筒。对于字母“I”,竖着划一下。但是,你很快就会发现,这个方法也不太行得通。当你看着朋友的手电筒在空中圈圈点点时,会发现很难在头脑中组合出那么多复杂的笔画。这些旋转和倾斜的光线都太不准确了。

或许大家都曾经在电影里看到这样的情节,两个水手在海上通过灯的亮灭来互相发送信号。而在另一部电影里,一个间谍转动一面镜子将太阳光反射到另一个房间里,从而向被俘的同伙传递信息。或许那正是解决问题的办法。如此一来,你就可以发明一种简单的技术。在这个方案里,字符表里的每个字符对应一连串的手电筒闪烁。“A”是闪一次,“B”是闪两次,“C”是闪三次,依此类推,“Z”就是闪26次。单词BAD可以用闪2次,闪1次,闪4次这样的一个组合来表示,而且在字符之间设置的小停顿使这个单词不至于被误认为是闪7次的字母“G”。另外,单词之间停顿可以稍长些。

这似乎很有希望,采用这种方案的好处是你不必在空中比划手电筒了,只要对准方向和按开关就行了。但是这种方案也有一个不足,那就是如果你想发送的第一个消息是“How are you?”,那么你将总计需要让手电筒闪131次!而且,这还是忽略了标点符号的,你还没有设计闪多少次来对应一个问号。

但是这已经离答案更近一些了。我们能够肯定的是,在此之前一定有人也遇到过类似的问题,而你解决这个问题的思路也是非常正确的。等到了白天,跑一趟图书馆,查查资料,你发现了一个被称为莫尔斯电码(Morse Code)的伟大发明。这正是你想找的,尽管你现在必须重新学习如何去“写”字母表里的字母。

它们的不同之处在于:在你发明的系统里,字母表里的每个字母就是用一定数目的闪光表示的,闪1下为“A”,闪26下为“Z”。而在莫尔斯电码里,则有两种闪烁——短闪和长闪。当然这使得莫尔斯电码更加复杂,但是在实际应用里它被证明是更为有效的。句子“How are you?”现在只要闪32下(包含一些短闪和一些长闪),而不再是131下,而且这其中还包括了一个代表问号的编码。

当问及莫尔斯电码是如何工作的时候,人们并不会谈论“短闪”与“长闪”。相反,他们使用“点(dot)”和“划(dash)”,因为这是在打印纸上显示编码的一个便利方法。在莫尔斯电码里,字母表里的每个字母都与一个点划序列相对应,正如下表所示。

虽然莫尔斯电码和计算机毫无关系,但是,熟悉编码的本质对于深入理解计算机软硬件内部结构以及隐匿在其后的语言将大有裨益。

在这本书里,编码这个词的意思是指一种用来在机器和人之间传递信息的方式。换句话说,编码就是交流。有时候我们认为编码就是指秘密的东西(密码)。但是大部分编码不是这样的。毕竟,大部分编码必须易于理解,因为它们是人类交流的基础。

在《百年孤独》这本书的开篇里,加西亚·马尔克斯回忆了一个时代,那时“这个世界刚刚出现,以至于很多东西缺乏命名,这时就有必要亲自用手指明这些事物”。我们赋予这些东西名字时往往是很随意的。这就好比说为什么猫不被叫做“狗”而狗不被叫做“猫”一样,没有什么理由可言。你可以说英语词汇就是一类编码。

对任何能听见我们的声音并理解我们所说的语言的人来说,我们发出的声音所形成的词语是一种可识别的编码。我们将这个编码称为“口头话语(the spoken word)”或“言辞(speech)”。对于写在纸上(或刻在石头上、木头上,或者在空气中比划)的词,我们还有其他的编码方式。这种编码以手写字符或打印在报纸、杂志以及书本上的字符形式出现。我们叫它“书面语言(the written word)”或“文本(text)”。在许多语言里,语言和文字之间存在着很紧密的联系。例如,英语中的字母和字母组合与它们的发音(或多或少)存在一定的对应性。

对于那些丧失听说能力的的聋哑人而言,人们发明了另一种编码来帮助他们进行面对面的交流。这就是手语。手语通过手和臂膀形成的动作和姿势来传达词语中的单个字符或者整个词语,以及基本的概念。对于那些失明的人,书面语言可以用布莱叶盲文(Braille)来替代。这种文字使用一系列凸起的点来代表字母、字母串以及整个单词。当话语必须快速抄成文本时,缩写和速记都是很有用的。

我们使用各种不同的编码来为我们自己的交流服务,因为有些编码有时比其他编码更便捷。例如,话语的编码不能存储在纸上,因此,书写的编码就被用来替代话语的编码。如果在黑暗的环境下,而且交流的双方之间有一定的距离,那么通过讲话或者文字来进行秘密的信息交换几乎是不可能的,因此,莫尔斯编码就成了一个方便的选择。如果一种编码可以用在其他编码无法取代的地方,那么它就是一种有用的编码。

我们将会看见,各种类型的编码也用在计算机里来存储和传递数字、声音、音乐、图片和电影。计算机不能直接处理人类的编码,因为计算机无法通过与人类的眼睛、耳朵、嘴巴和手指完全相同的方式来接收人类发出的信息。然而,计算机技术的一个最新趋势,已使得我们的个人计算机能够获取、存储、处理和呈现一切用于与人类沟通的信息,无论视觉信息(文字和图片),还是听觉信息(口语、声音和音乐),或两者的相结合(动画和电影)。所有这些类型的信息都需要它们各自的编码,就像人类说话需要一套器官(嘴和耳朵)而写作和阅读需要另一套(手和眼)一样。

甚至前面所列的莫尔斯编码表,其本身就是一种类型的编码。在这个表中,每个字母由一系列的“点”和“划”来表示。然而实际上我们不能发送“点”和“划”,相反,我们发送与“点”和“划”对应的闪烁光。

当使用手电筒发送莫尔斯编码时,迅速地打开和关闭开关代表一个“点”(快闪),让闪光时间保持得相对长一些代表“划”(慢速闪光)。例如在发送字母A时,首先以非常快的速度打开并关闭手电,然后再以稍慢的速度进行一次。在发送下一个字符前,需要暂停一会。在此约定,一个“划”的时长是“点”的3倍。例如,如果一个“点”的时长是1秒钟,那么一个“划”的时长就应当是3秒钟。(在现实中,莫尔斯编码的传输速度远比这要快得多)。接收者看到一个短促的闪烁和一个拖长的闪光后,就知道这是一个A了。

在莫尔斯编码中,“点”和“划”之间的停顿是至关重要的。例如,当发送一个字母A时,在发送的“点”和“划”之间,手电筒要关闭一段时间,这相当于一个点的闪烁时长(如果“点”的时长是1秒钟,那么“点”和“划”之间的停顿也应该是1秒钟)。对于同一个单词中的字母,则通过较长的停顿来分隔,这大约相当于一个“划”的时长(或者说是3秒钟,如果一个“划”的时长就是3秒钟的话)。下图以“hello”的莫尔斯编码为例,说明字母之间的停顿(间隙)。

单词之间则通过相当于两个“划”的时长来分隔(如果一个“划”的时长为3秒钟,那么这个停顿就应当为6秒钟)。例如下图是“hi there”所对应的编码。

手电筒开和关的时长并没有限定。它们都与一个“点”的时长相关,而这依赖于手电筒开关能以多快的速度扳动,以及莫尔斯编码的发送者能以多快的速度记下一个指定字符。对于一个快速发送者,他的“划”的时长,也许只相当于一个慢速发送者的“点”的时长。这会带来一个小问题,即阅读莫尔斯编码信息会变得很困难,但是经过一两个字母之后,接收者通常就可以分清楚哪一个是“点”,哪一个是“划”了。

乍一看,莫尔斯编码的定义与打字机字母的排列一样都是随意的。这里的定义是指字母表中的字母与各种“点”和“划”的组合序列之间的对应关系。然而,仔细研究之后,我们就会发现事实并非完全如此。简单且短促的编码,被分配给字母表中使用频率较高的字母,例如E和T。拼字比赛选手和“幸运轮”的粉丝们可能会很快意识到这一点。而不太常用的字母,比如Q和Z(这只会让选手在拼字中得到10分)则被分配以较长的编码。

几乎每个人都知道一点儿莫尔斯编码。三个点、三个划,再加三个点就表示SOS,即国际求救信号。SOS不是一个缩写,这只是一个易于记忆的莫尔斯编码序列。在第二次世界大战期间,英国广播公司一些无线电广播以贝多芬第五交响曲的片段来作为节目的前奏——BAH,BAH,BAH,BAHMMMMM,而贝多芬绝不会想到他所谱写的这段乐曲可以表示为莫尔斯编码的V,即胜利(Victory)之意。

莫尔斯编码的一个缺点是,它没有区分大写字母和小写字母。但是除了可以代表字母外,莫尔斯编码还使用一组由点和划组成的五元序列来表示数字,如下所示。

这些编码至少比字母编码更有规律一些。大部分标点符号由5个、6个或者7个“点”和“划”的组合序列来表示,如下所示。

还有一些编码则用来表示某些欧洲语言中的重音字母,以及用于特殊目的的速记序列。如SOS的编码就是这样的一个速记序列:必须连续地传递这三个字母,而且字母之间只有一个点的停顿时间。

如果有一个专门为此设计的手电筒的话,你会发现和朋友之间通过莫尔斯编码交流将变得更加简单。除了一个可以滑动的开关外,这种手电筒还有一个按钮开关用来控制灯光的明灭。在一些实际应用中,可以达到每分钟传递5到6个单词的速度——虽然这仍比讲话慢得多(讲话的速度在每分钟100个单词左右),但这已经足够了。

当你和朋友最终熟记了莫尔斯编码之后(这是能熟练地收发编码的唯一方法),你们甚至可以在口语中使用它,用来取代正常的语言。为了使编码发送的速度最快,你可以把“点”读作“嘀(dib)”,把“划”读作“嗒(dab)”。文字也可以用同样的方式简化成“点”和“划”的序列,莫尔斯编码的口语版把讲话内容缩减到只剩下两个声音了。

问题的关键就在于数字2。两种闪烁,两种声音。事实上,两个不同的事物,只要经过适当的组合,就可以表示所有类型的信息,这的确是千真万确的。