【Python】摩斯电码高级加解密算法(附字典+代码)

前言

摩斯电码(Morse Code),又名摩尔斯电码,是计算机未普及时常用的信息传递工具,常搭配摩尔斯电报机使用。

摩尔斯电码是由美国人摩尔斯在1837年被发明的,它的组成是由点dot(.)划dash(-)这两种符号所组成的。——百度百科

随着信息技术发展,这种低效的信息传递方式已经被淘汰,现在只有业余工作者使用。但是作为一个曾在历史上大有影响的东西,其现在反而发展成了一种加密方式(尽管它是字典加密)。当然,负责加密和解密的不是人,是机器。

今天就分享一个自己写的一个摩斯电码加解密算法。

正文

本来这个东西网上搜索的话结果会很多,但是『疾客出品,必属精品!』嘛,我的这个小项目和那些千篇一律的答案还是有些不一样的,总之先概括它的两个特色:

支持非英文字符支持英文区分大小写

代码

'''
@File    :   morsecode.py
@Time    :   2023/03/25 17:14:09
@Author  :   @灰尘疾客
@Version :   1.0
@Site    :   https://www.gkcoll.xyz
@Desc    :   A simple but advanced Morse Code encryption & decryption realization.
'''

MORSEDICT = {'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': '--..',
             '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': '-----',
             '/': '-..-.', '+': '.-.-.', '=': '-...-', '.': '.-.-.-', ':': '---...',
             ',': '--..--', ';': '-.-.-.', '?': '..--..', '\'': '.----.', '!': '-.-.--',
             '-': '-....-', '_': '..--.-', '"': '.-..-.', '(': '-.--.', ')': '-.--.-',
             '$': '...-..-', '&': '......', '@': '.--.-.'}
QUERYDICT = {v: k for k, v in MORSEDICT.items()}

def get_cipher(plain: str) -> str:
    if plain in MORSEDICT.keys():
        cipher = MORSEDICT[plain]
    else:
        # 非英文和英文标点的处理方法
        bin_unicode = bin(ord(plain)).lstrip("0b")
        cipher = bin_unicode.replace("1", "-").replace("0", ".")
    return cipher

def get_clear(code: str) -> str:
    if code in QUERYDICT.keys():
        clear = QUERYDICT[code]
    else:
        # 密文无对应明文的情况
        bin_unicode = code.replace("-", "1").replace(".", "0")
        clear = chr(int(bin_unicode, 2))
    return clear

def encrypt(plain: str) -> str:
    ciphertext = str()
    for letter in plain:
        ciphertext += get_cipher(letter) + "/"
    return ciphertext.rstrip("/")

def decrypt(cipher: str) -> str:
    cleartext = str()
    codes = cipher.split("/")
    for code in codes:
        cleartext += get_clear(code)
    return cleartext

def auto(obj: str = "gkcoll") -> str:
    for i in obj:
        if i not in [".", "-", "*", "~", "/"]:
            return encrypt(obj)
        else:
            pass
    return decrypt(obj)

print(decrypt("*"))

详解

首先请大家原谅我注释留得很少——只有两句,但是我相信这写得像自然语言的代码各位阅读起来并不难。

中文处理

其中有加注释的两个代码块,就是中文等非英文字符的处理方式。

我参考了网上很多工具,并通过 DevTools 查看了它们对应的加密脚本文件,看到了解决方式:转 Unicode 编码(十进制整数),再转二进制(二进制字符串),最后替换字符串(1 => -, 0 => .)。解密则是逆向这个过程,无需赘述。

对应的就是上方 Python 代码的 35、36 行。

print(encrypt("极客藏源万岁"))
# --..----......-/-.--.---.-...-./-....-.---..----/--.---.-..-..../-..---......---/-.---..-......-

区分大小写

代码头部注释下定义了两个常量,分别是摩斯电码字典和反向字典(分别用于获取密文和明文)。

MORSEDICT 中,我用 * 替换了 .,用 ~ 替换了 -,使之可以区分大小写,解决一些特定需求。

print(encrypt("Hello World!"))
# ****/./.-../.-../---/-...../*~~/---/.-./.-../-../-.-.--

自动获取

本来我并不想开发这个功能,但是实在怕某些人连明文或密文都分不清(或者加密解密两个单词都不会拼),所以开发了这个功能。

代码逻辑可能有点让人混淆,其实就是一个判断:出现任何一个非密文字符则返回加密结果,全为密文字符则返回解密结果。

print(auto("****/./.-../.-../---/-...../*~~/---/.-./.-../-../-.-.--"))
# Hello World!

你完全可以复制我的代码用于您的项目中且无需保留我的版权信息,因为它遵守 WTFPL 进行开源。但我还是希望你能在评论区留下积极的回复,给我坚持下去的动力。

阅读剩余
THE END