如何使用 Python 创建一个摩尔斯电码转换器

莫尔斯电码是一种利用点、划和空格来对信息进行编码的系统。 它常被用于秘密地传递消息。

您或许在很多电影中的海军场景里看到过使用莫尔斯电码进行通信的情景。 我们这里讨论的正是同一种莫尔斯电码,但不同之处在于,我们将编写一个Python程序来实现英语和莫尔斯电码之间的互相转换。

认识摩尔斯电码

摩尔斯电码为每个英文字母、数字、标点符号和一些非拉丁字符都设定了独特的点划组合。 一旦你掌握了这些符号的对应规则,对它们进行编码和解码就变得相当容易了。 你可以参考维基百科关于摩尔斯电码的页面,获取更多详细的信息和编码模式。

在本教程中,我们将学习如何把纯英文文本转换成莫尔斯电码,反之亦然。 在进行编码解码的过程中,我们将使用英文字母、数字和常见的标点符号。 如果您想加入更多类型的字符,只要理解了编码和解码的原理,您就可以轻松地扩展实现。

需要记住的是,大写字母和小写字母在莫尔斯电码中具有相同的模式。 这是因为莫尔斯电码主要用于对字母大小写不敏感的交流,如日常对话等。

现在,让我们开始进入编码和解码的实际操作部分。

英文转摩尔斯电码

将纯英文文本转换为摩尔斯电码的算法并不复杂。 让我们一步步分析这个算法。

  • 创建一个字典,将英文字母、数字和标点符号与它们对应的莫尔斯电码模式进行映射。
  • 遍历输入的文本,将每个字符对应的莫尔斯电码模式添加到结果字符串中。
    • 每个字符的莫尔斯电码后面需要添加一个空格,而每个单词之间则需要添加两个空格。
    • 因此,当我们在文本中遇到空格,即单词的分隔符时,我们需要在结果中添加双倍空格。
  • 最终的字符串就是我们所需要的莫尔斯电码。
  • 最后,返回这个结果。

试着使用Python来编写代码。 不必担心,即使你不能完整地写出代码,也没有问题。

现在让我们看看如何实现将纯英文文本编码为莫尔斯电码的代码。

    
# 字符到摩尔斯电码的映射字典
CHARS_TO_MORSE_CODE_MAPPING = {
    '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': '--..',
    '1': '.----',
    '2': '..---',
    '3': '...--',
    '4': '....-',
    '5': '.....',
    '6': '-....',
    '7': '--...',
    '8': '---..',
    '9': '----.',
    '0': '-----',
    '.': '.-.-.-',
    ',': '--..--',
    '?': '..--..',
    '\'': '· − − − − ·',
    '!': '− · − · − −',
    '/': '− · · − ·',
    '(': '− · − − ·',
    ')': '− · − − · −',
    '&': '· − · · ·',
    ':': '− − − · · ·',
    ';': '− · − · − ·',
    '=': '− · · · −',
    '+': '· − · − ·',
    '-': '− · · · · −',
    '_': '· · − − · −',
    '"': '· − · · − ·',
    '$': '· · · − · · −',
    '@': '· − − · − ·',
}

# 将纯英文文本编码为莫尔斯电码的函数
def to_morse_code(english_plain_text):
    morse_code=""
    for char in english_plain_text:
        # 检测空格
        # 每个字符后添加一个空格,每个单词后添加两个空格
        if char == ' ':
            morse_code += '  '
        else:
            # 将编码后的莫尔斯电码添加到结果
            morse_code += CHARS_TO_MORSE_CODE_MAPPING[char.upper()] + ' '
    return morse_code

morse_code = to_morse_code(
    'techblik.com produces high-quality technology & finance articles, makes tools, and APIs to help businesses and people grow.'
)
print(morse_code)
    
    

您可以在下面看到莫尔斯电码的输出结果。 如果你没有修改消息内容,你应该在终端中看到类似的输出。

    
--. . . -.- ..-. .-.. .- .-. .   .--. .-. --- -.. ..- -.-. . ...   .... .. --. .... − · · · · − --.- ..- .- .-.. .. - -.--   - . -.-. .... -. --- .-.. --- --. -.--   · − · · ·   ..-. .. -. .- -. -.-. .   .- .-. - .. -.-. .-.. . ... --..--   -- .- -.- . ...   - --- --- .-.. ... --..--   .- -. -..   .- .--. .. ...   - ---   .... . .-.. .--.   -... ..- ... .. -. . ... ... . ...   .- -. -..   .--. . --- .--. .-.. .   --. .-. --- .-- .-.-.-
    
    

干得漂亮! 我们得到了莫尔斯电码。 现在你知道下一步该怎么做了。

在开始进行解码程序之前,让我们先停下来思考一下,如何编写代码来对其进行解码。

您应该考虑将CHARS_TO_MORSE_CODE_MAPPING 字典作为反向查找的工具。 如果手工操作,工作量会很大,并且当原始映射发生改变时还需要更新。 让我们编写代码来反转这个字典。

    
def reverse_mapping(mapping):
    reversed = {}
    for key, value in mapping.items():
        reversed[value] = key
    return reversed
    
    

我们使用上面的代码来反转给定字典的键值对。 反转后的字典会将原字典的值作为键,原字典的键作为值。

我们已经准备好了将莫尔斯电码解码为纯英文文本的所有要素。 事不宜迟,让我们开始解码莫尔斯电码。

莫尔斯电码转英文

我们可以将莫尔斯电码编码的过程逆转,从而得到解码的算法。 让我们来看看将莫尔斯电码解码为纯英文文本的算法:

  • 使用我们前面编写的工具函数来反转 CHARS_TO_MORSE_CODE_MAPPING 字典。
  • 遍历莫尔斯电码,并跟踪当前正在处理的莫尔斯电码字符。
    • 如果我们遇到一个空格,这意味着我们得到了一个完整的莫尔斯电码字符,需要进行解码。
      • 如果当前莫尔斯电码字符为空,并且我们遇到了两个连续的空格,那么添加一个单词分隔符,即纯英文文本中的一个空格。
      • 如果上述条件不成立,则从字典中查找该莫尔斯电码字符对应的英文,并将其添加到结果中。 重置当前的莫尔斯电码字符。
    • 如果我们没有遇到空格,那么将当前字符添加到正在处理的莫尔斯电码字符中。
  • 如果存在最后一个尚未处理的字符,请使用字典进行解码并将其添加到结果中。
  • 最后,返回结果。

让我们看看上述算法对应的代码实现。

    
def reverse_mapping(mapping):
    # 添加前面代码片段中的函数代码...
    reversed = {}
    for key, value in mapping.items():
        reversed[value] = key
    return reversed

CHARS_TO_MORSE_CODE_MAPPING = {
    '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': '--..',
    '1': '.----',
    '2': '..---',
    '3': '...--',
    '4': '....-',
    '5': '.....',
    '6': '-....',
    '7': '--...',
    '8': '---..',
    '9': '----.',
    '0': '-----',
    '.': '.-.-.-',
    ',': '--..--',
    '?': '..--..',
    '\'': '· − − − − ·',
    '!': '− · − · − −',
    '/': '− · · − ·',
    '(': '− · − − ·',
    ')': '− · − − · −',
    '&': '· − · · ·',
    ':': '− − − · · ·',
    ';': '− · − · − ·',
    '=': '− · · · −',
    '+': '· − · − ·',
    '-': '− · · · · −',
    '_': '· · − − · −',
    '"': '· − · · − ·',
    '$': '· · · − · · −',
    '@': '· − − · − ·',
}
MORSE_CODE_TO_CHARS_MAPPING = reverse_mapping(CHARS_TO_MORSE_CODE_MAPPING)

def to_english_plain_text(morse_code):
    english_plain_text=""

    current_char_morse_code=""
    i = 0
    while i < len(morse_code) - 1:
        # 检查每个字符
        if morse_code[i] == ' ':
            # 检查单词
            if len(current_char_morse_code) == 0 and morse_code[i + 1] == ' ':
                english_plain_text += ' '
                i += 1
            else:
                # 将解码后的字符添加到结果
                english_plain_text += MORSE_CODE_TO_CHARS_MAPPING[
                    current_char_morse_code]
                current_char_morse_code=""
        else:
            # 将莫尔斯电码字符添加到当前字符
            current_char_morse_code += morse_code[i]
        i += 1

    # 将最后一个字符添加到结果
    if len(current_char_morse_code) > 0:
        english_plain_text += MORSE_CODE_TO_CHARS_MAPPING[
            current_char_morse_code]

    return english_plain_text

english_plain_text = to_english_plain_text(
    '--. . . -.- ..-. .-.. .- .-. .   .--. .-. --- -.. ..- -.-. . ...   .... .. --. .... − · · · · − --.- ..- .- .-.. .. - -.--   - . -.-. .... -. --- .-.. --- --. -.--   · − · · ·   ..-. .. -. .- -. -.-. .   .- .-. - .. -.-. .-.. . ... --..--   -- .- -.- . ...   - --- --- .-.. ... --..--   .- -. -..   .- .--. .. ...   - ---   .... . .-.. .--.   -... ..- ... .. -. . ... ... . ...   .- -. -..   .--. . --- .--. .-.. .   --. .-. --- .-- .-.-.- '
)
print(english_plain_text)
    
    

我已经给出了从编码函数生成的莫尔斯电码。 如果我们运行上述程序,我们将得到以下输出。

        
techblik.com PRODUCES HIGH-QUALITY TECHNOLOGY & FINANCE ARTICLES, MAKES TOOLS, AND APIS TO HELP BUSINESSES AND PEOPLE GROW.
        
    

注意:输出是英文大写字母,因为我们在字典中使用了大写字母进行映射。

总结

我们已经看到解码函数的输出是全大写的。 你可以通过跟踪英文字母的大小写来改进程序,使得输出保持与输入一致的大小写。 这与莫尔斯电码本身没有关系,因为大小写具有相同的点划模式。 不妨尝试一下,这会给你的编码过程增添更多乐趣。

这就是本教程的全部内容。 下次你遇到莫尔斯电码时,不妨使用我们编写的程序。

祝您编码愉快! 👨‍💻

您还可以了解一下如何在Python中生成随机密码