目前,能找到的最古老的系统化字符编码,似乎就是摩尔斯电码了(Morse code),我们今天就来探寻一番。
许多人对摩尔斯电码最深刻的记忆,都来自同一部电影:《无间道》。
在《无间道》三部曲中,多次出现摩尔斯电码的身影:
- 陈永仁逃跑时敲击墙壁,在天台山敲击自己的胳膊,交易时通过窃听器传输摩尔斯电码报信;
- 警局卧底的档案密码是摩尔斯电码;
- 最后刘建明在轮椅上敲出了 HEL …,却没人知道最后一位字母是什么
以上这些都是大家津津乐道的情节,可以说,摩尔斯电码几乎成为了谍战类影视剧的标配。
那么,就先从它开始探索吧。
摩尔斯电码
编码表
摩尔斯电码的一个特点就是所有的字母并不是等长的,我们可以从它的编码表中直观的看到。
其实换一种方式来看这张编码表,会更好理解,因为这其实就是一棵霍夫曼树(Huffman Tree)。
这里使用霍夫曼树的原因也很简单,英文字符在日常使用中是有频率差异的,这棵树大致就是按照这个频率进行构建。
与常见的霍夫曼编码略有不同的是,常见的霍夫曼编码只有叶子节点才会分配给字符,而摩尔斯电码非叶子节点也被分配了字符,也就是说,摩尔斯电码并不是前缀编码,这也间接导致了接下来我们要讨论的结构问题。
工具推荐:
由独特工具箱提供的摩尔斯电码编码解码工具,可以对数字、英文、标点符号字符进行编码解码。
结构组成
首先,我们问一个问题:摩尔斯电码,只包含点和中横线吗?
如果不仔细翻看资料,可能大部分人会认为摩尔斯电码是由 ·
和 -
组成的,也就是我们常说的「点」和「中横线」,也可以写作 dot
和 dash
。
- 点 / dot / · / 滴 / di
- 划 / dash / - / 嗒 / dah
但是实际上,无论从什么角度来考虑,摩尔斯电码都不止包含这两个元素。
先来简单测试一下,如果我们只使用 ·
和 -
来编码 hello world
会怎样:
这好像和我们经常见到的不一样,难道不应该是这样的么?
另一个角度,我们知道 -
实际上是三倍长度的 ·
。
那么,假如我发送了 ...
,我要发送的是 S
呢?还是 EEE
呢?还是 T
呢?
隐藏的分隔符
此时我们似乎发现了一个隐藏的字符,那就是空格,或者叫分隔符。
我们都知道,使用摩尔斯电码发送电报的时候需要使用「电键」,而电键的基础原理其实就是控制电路在「通」「断」两种状态间切换,通过按下时长的长短来区分「点」「中横线」。
也就是说,「点」与「点」之间,「字符」与「字符」之前,其实是通过间隔来进行分隔的。
我们假定一个「点」的时长为一个单位长度 T
,那么「中横线」的时长就是 3T
。
同一个字符内部的「点」「中横线」间的间隔也是 T
,字符间的间隔是 3T
,而单词间的间隔则是 7T
。
此处我们选择两个字符 O
和 R
作为示意,在发报的过程中,电路的通断情况其实是下面这样的:
这样,我们就可以用简单的「通」「断」来表示出摩尔斯电码了。
原来是二进制
其实看到上面的示意图就会发现,其实电路状态的「通」「断」,完全可以理解为二进制的 1
和 0
,而摩尔斯电码的基本组成结构,也可以理解为只有「通」「断」。
当然,我们也可以理解按常见的方式去理解它的结构,只是这下我们知道它背后的底层内容了。
- 点 (1)
- 划 (111)
- 分隔符
- 点划分隔 (0)
- 字符分隔 (000)
- 单词分隔 (0000000)
可以看到,其实 OR
的摩尔斯编码,其实也可以用二进制 1
和 0
来进行表示:
OR => 010111010001011101010
其实换一个角度也很容易想明白,基于电路通断的摩尔斯电码,不论上层怎么定义,都不可能绕开底层只有两种状态这件事。
传输效率
从上面的示意图中,其实我们还能发现另一个问题,摩尔斯电码的效率并不高。
发送 OR
两个字符,总共用了 21T
的时长,操作手按下电键 7 次,这个效率用作信息传递不免让人觉得有些焦躁。
于是,就有了各种提升摩尔斯电码效率的操作。
信息压缩
需要说明的是,需要被压缩的并不是摩尔斯电码,而是英文单词。
正如许多人使用 tks
来代指 thanks
,BTW
来代指 by the way
一样,英文世界里也存在着大量的对常用词汇的缩写。一百多年前的前辈们,也是对它进行了充分的利用。
这些缩写分为两类,一类是简单的拼接字符,形成短词,相当于单词缩写。
另一类则是直接造了新的字符出来,称为特殊符号(统一符号)。
单词缩写
单词缩写的例子非常多,这里简单列举一小部分。
可以看到,这些词汇大部分都是首字母缩写,许多缩写后面也有了更广泛的用法。
缩写 | 全写 | 注释 |
---|---|---|
AA | All after | 某字以后 |
AB | All before | 字以前 |
BN | All between | ……之间 |
C | Yes | 是,好 |
CQ | Calling any station | 调用任意台站 |
CUL | See you later | 再见 |
CY | Copy | 抄收 |
DE | From | 来自 |
GA | Good afternoon or Go ahead | 午安;请发报(依上下文而定) |
GE | Good evening | 晚安 |
GM | Good morning | 早安 |
HI | Laughter | 笑 |
R | Received,Roger or decimal point | 收到;小数点(依上下文而定) |
RPT | Repeat or report (depending on context) | 重复;报告(依上下文而定) |
RX | Receive | 接收 |
TNX | Thanks | 谢谢 |
TU | Thank you | 谢谢你 |
TX | Transmit | 发射 |
U | You | 你 |
UR | Your or you’re | 你的;你是(依上下文而定) |
73 | Best regards | 致敬 |
88 | Love and kisses | 吻别 |
99 | go way | 走开(非友善) |
特殊符号
特殊符号的主要特点在于各个原本的字符之间,是不存在字符间隔的,符号整体相当于一个字符。
可以看到的是,K
、T
、R
等单个字符,也直接被赋予了特殊涵义。
符号 | 代码 | 意义 |
---|---|---|
AAAAA | ·-·-·-·-·- |
调用信号,表示“我有消息发送”。 |
AAA(.) | ·-·-·- |
表示“本句完,接下一句”。 |
HH | ········ |
表示“有错,从上一字重新开始”。 |
AR(+) | ·-·-· |
表示“消息结束”。 |
AS(&) | ·-··· |
等待。 |
TTTTT | ----- |
表示“我正在接收你的消息”。 |
K | -·- |
表示“我已准备好,请开始发送消息”。 |
T | - |
表示“字收到了”。 |
IMI(?) | ··--·· |
表示“请重复你的电码,我不是很明白”。 |
R | ·-· |
表示“消息已收到”。 |
SK | ···-·- |
表示终止(联系结束)。 |
BT(=) | -···- |
分隔符。 |
SOS | ···---··· |
求救信号。 |
通过以上这些缩写和特殊符号,就可以将一次沟通所需的字符尽可能压缩了,例如维基百科上所列出的这个示例:
s1:
CQ CQ CQ DE s1 K
呼叫任何人(CQ),這是(DE)s1,結束(K)。
s2:
s1 DE s2 K
呼叫s1,這是s2,結束。
(現在兩個電台就建立通訊連接了)
s1:
SK
再見。
s2:
SK
再見。
可以看到,对话双方,仅用 30 个字符就完成了一次对话的建立和结束,这极大的提升了使用摩尔斯电码沟通的效率。
电键改造
除了尽可能的压缩要发送的信息,提升发报员的手速自然也是一个重要的方向。
但是好马也要配好鞍,发报员离不开的电键也需要好好花功夫进行升级。
手动电键
传统的手动电键的原理非常简单,触点 + 弹簧,发报员通过按下或松开触点的动作来完成发报。
这个过程完全手动完成,发报员的按键频率,直接决定了发报的速率。
臭虫电键
臭虫电键也叫快键,也就是机械半自动电键。
之所以叫它半自动,是因为它实现了「点」的自动发送:
- 将按键向右拨,会发出「点」,一直按住不放,会按相应的频率一直发送「点」直到松手
- 将按键向左拨,会发出「中横线」,但是此处不具备按住一直发送的功能
即便只是半自动,臭虫电键也已经节约了不少时间。
单杆电子键
单杆电子键其实就是全自动版的臭虫电键,它不止可以通过长时间向右按键发出连续的「点」,长时间向左按键也可以发出连续的「中横线」,这下子就算完整的自动化了。
双杆电子键
双杆电子键乍一看好像和单杆的没什么区别,也是左桨「点」,右桨「中横线」,其实它还加入了第三种重要的自动功能:挤压双桨,就会自动发送「点」和「中横线」间隔的序列,这对于特定的字母和符号非常有效。
总结
从现在的角度来看,摩尔斯电码存在许多问题,性能差,长度不统一等等。
但更需要看到的是,它的许多优秀之处:
- 使用「点」「中横线」对底层的
0
和1
进行包装,更易于被人理解。 - 使用霍夫曼树、缩写词等方式,尽可能减小数据体长度,节约带宽。
- 改进辅助工具,提升工作效率。
同时,也需要认识到一个重要的误区:编码的组成结构,未必就是表面上看到的那样。
最后,这里有一张摩尔斯电码助记图,想要学习的可以参考一下:
感谢阅读,希望本文对你理解摩尔斯电码有一定对帮助。