摩斯电码(Morse Code)是少数几种人类可以只用手电筒或手指就能发送、靠耳朵就能解码的编码系统之一。它诞生于 1830 年代,至今仍在无线电爱好者圈子里活跃使用。这篇文章讲清楚摩斯电码的工作原理、完整字母表、双向翻译逻辑,以及如何用代码实现。
摩斯电码简史
Samuel Morse 和 Alfred Vail 在 1830 年代研发出摩斯电码,配套电报机使用。系统用电流长短——点(短)和划(长)——来表示字母和数字。
1844 年 5 月 24 日,第一条长途电报从华盛顿特区发往巴尔的摩:“上帝赐予了什么(What hath God wrought)。“从此,信息传递速度第一次达到了电的速度,而不是马的速度。
摩斯电码主导远程通信超过一个世纪。国际海事通信正式停用摩斯电码是在 1999 年。
摩斯电码的基本原理
摩斯电码将每个字母和数字映射为一串点(·)和划(—)的组合:
- 点(·):短信号,持续时间 = 1 单位
- 划(—):长信号,持续时间 = 3 单位
- 同一字母内符号间隔:1 单位
- 字母间隔:3 单位
- 单词间隔:7 单位
时间比例关系是核心:划是点的 3 倍长,单词间隔是点的 7 倍长。这个固定比例让熟练操作员的发送速度可以超过每分钟 25 个单词。
摩斯电码字母表
字母
| 字母 | 编码 | 字母 | 编码 | 字母 | 编码 |
|---|---|---|---|---|---|
| A | ·— | J | ·——— | S | ··· |
| B | —··· | K | —·— | T | — |
| C | —·—· | L | ·—·· | U | ··— |
| D | —·· | M | —— | V | ···— |
| E | · | N | —· | W | ·—— |
| F | ··—· | O | ——— | X | —··— |
| G | ——· | P | ·——· | Y | —·—— |
| H | ···· | Q | ——·— | Z | ——·· |
| I | ·· | R | ·—· |
数字
| 数字 | 编码 | 数字 | 编码 |
|---|---|---|---|
| 0 | ————— | 5 | ····· |
| 1 | ·———— | 6 | —···· |
| 2 | ··——— | 7 | ——··· |
| 3 | ···—— | 8 | ———·· |
| 4 | ····— | 9 | ————· |
常用标点
| 符号 | 编码 |
|---|---|
| . (句号) | ·—·—·— |
| , (逗号) | ——··—— |
| ? (问号) | ··——·· |
| / (斜杠) | —··—· |
程序缩语(Prosign)
程序缩语是两个字母的组合,但发送时没有字母间隔——作为单一单元使用,具有特殊含义。在历史电报记录和业余无线电通联中常见:
| 缩语 | 含义 |
|---|---|
| AR | 消息结束 |
| AS | 等待 |
| CQ | 呼叫任意电台 |
| DE | ”来自”(标识发送方) |
| K | 请对方发送(Over) |
| SK | 通联结束 |
| SOS | 遇险信号(···———···) |
SOS 是最著名的:三点三划三点。之所以选这个组合,是因为它完全对称,从任何方向读都一样,在紧急情况下最容易识别。
双向翻译原理
文字 → 摩斯码:查表,把每个字符替换为对应的点划序列。单词之间用 / 分隔。这个方向没有歧义——每个字符只有一个摩斯表示。
摩斯码 → 文字:按空格分割每个字母的编码,按 / 分割单词,反向查表还原字符。格式正确的摩斯码有唯一解码结果。
JavaScript 实现
const MORSE_MAP = {
'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': '--..',
'0': '-----', '1': '.----', '2': '..---',
'3': '...--', '4': '....-', '5': '.....',
'6': '-....', '7': '--...', '8': '---..',
'9': '----.'
};
const REVERSE_MAP = Object.fromEntries(
Object.entries(MORSE_MAP).map(([k, v]) => [v, k])
);
// 文字转摩斯码
function textToMorse(text) {
return text.toUpperCase().split('').map(char => {
if (char === ' ') return '/';
return MORSE_MAP[char] ?? '?';
}).join(' ');
}
// 摩斯码转文字
function morseToText(morse) {
return morse.split(' / ').map(word =>
word.split(' ').map(code => REVERSE_MAP[code] ?? '?').join('')
).join(' ');
}
console.log(textToMorse('SOS')); // ... --- ...
console.log(morseToText('... --- ...')); // SOS
Python 实现
MORSE_MAP = {
'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': '--..',
'0': '-----', '1': '.----', '2': '..---',
'3': '...--', '4': '....-', '5': '.....',
'6': '-....', '7': '--...', '8': '---..',
'9': '----.',
}
REVERSE_MAP = {v: k for k, v in MORSE_MAP.items()}
def text_to_morse(text: str) -> str:
return ' '.join(
'/' if c == ' ' else MORSE_MAP.get(c.upper(), '?')
for c in text
)
def morse_to_text(morse: str) -> str:
return ' '.join(
''.join(REVERSE_MAP.get(code, '?') for code in word.split())
for word in morse.strip().split(' / ')
)
print(text_to_morse('HELLO')) # .... . .-.. .-.. ---
print(morse_to_text('.... . .-.. .-.. ---')) # HELLO
在树莓派上用 LED 发送摩斯码
import RPi.GPIO as GPIO
import time
LED_PIN = 18
DOT = 0.1 # 1 单位 = 0.1 秒
DASH = DOT * 3
SYMBOL_GAP = DOT
LETTER_GAP = DOT * 3
WORD_GAP = DOT * 7
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
def blink(duration):
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(duration)
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(SYMBOL_GAP)
def send_morse(morse_str):
for token in morse_str.split():
if token == '/':
time.sleep(WORD_GAP)
else:
for symbol in token:
blink(DOT if symbol == '.' else DASH)
time.sleep(LETTER_GAP)
send_morse(text_to_morse('SOS'))
GPIO.cleanup()
这是嵌入式开发的经典入门项目——硬件版”Hello World”。
实际应用场景
业余无线电(HAM):摩斯电码(CW 模式)在持证业余无线电操作员中至今活跃使用。CW 占用带宽极窄,抗干扰能力强,在嘈杂信道下比语音通信更可靠。
无障碍输入:iOS 和 Android 均支持摩斯码作为替代输入法,让无法正常使用触屏的用户可以通过单开关输入任意字符。
CTF 竞赛:摩斯电码隐写是 Capture The Flag 比赛的常见题型——音频波形或图片元数据中藏摩斯码。
嵌入式学习:用 LED 或蜂鸣器输出摩斯码,是树莓派/Arduino 入门的经典项目。
在线摩斯电码翻译
ZeroTool 摩斯电码翻译工具 支持文字与摩斯码的实时双向转换,覆盖 ITU 标准字母表、数字和常用标点。无需注册,全部在浏览器本地运行。