【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 进行开源。但我还是希望你能在评论区留下积极的回复,给我坚持下去的动力。