从贴吧神帖到实战:手把手教你用Python复刻那个经典的5层摩斯密码(附完整代码)
五层加密的浪漫:用Python还原经典摩斯密码表白术
2009年百度贴吧那个轰动一时的摩斯密码爱情故事,至今仍被技术爱好者津津乐道。当时一位男生为破解心仪女生设置的五层加密密码,在贴吧发起求助,最终在网友协作下成功解码出"I LOVE YOU TOO"的浪漫回应。作为Python开发者和密码学爱好者,我们今天将完整复现这个经典案例的破解过程,从摩斯电码转换到最终明文输出,用代码还原这段数字时代的罗曼史。
1. 环境准备与基础工具
在开始编写解密脚本前,我们需要准备Python开发环境和必要的密码学知识基础。现代Python生态提供了丰富的字符串处理工具,这正是我们实现多层密码转换的关键。
1.1 安装必要依赖
# 推荐使用Python 3.8+版本
import re
from collections import defaultdict
摩斯密码处理主要依赖Python标准库,无需额外安装包。正则表达式模块 re 将帮助我们高效处理电码符号的匹配和替换,而 defaultdict 则为建立各种映射表提供了便利。
1.2 摩斯电码基础对照表
MORSE_CODE_DICT = {
'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': '-----', ' ': '/'
}
这个字典完整定义了标准摩斯电码的字母数字对应关系。注意我们特别将空格字符映射为'/',这是处理原始电码分隔符的常见做法。
2. 第一层:摩斯电码解码
原始密码字符串如下: ****-/*----/----*/****-/****-/*----/---**/*----/****-/*----/-****/***--/****-/*----/----*/**---/-****/**---/**---/***--/--***/****-/
2.1 电码符号标准化处理
def normalize_morse(morse_str):
# 将视觉符号转换为标准摩斯符号
morse_str = morse_str.replace('*', '.').replace('-', '-')
# 统一分隔符处理
return morse_str.replace('/', ' ')
这个预处理函数将星号(*)转换为点(.),保持横线(-)不变,同时统一分隔符格式。标准化后的电码串更符合常规摩斯电码的表示形式。
2.2 摩斯电码到数字的解码
def morse_to_numbers(morse_str):
normalized = normalize_morse(morse_str)
reverse_dict = {v: k for k, v in MORSE_CODE_DICT.items()}
decoded = []
for code in normalized.split():
decoded.append(reverse_dict.get(code, ''))
return ''.join(decoded)
执行解码:
original_code = "****-/*----/----*/****-/****-/*----/---**/*----/****-/*----/-****/***--/****-/*----/----*/**---/-****/**---/**---/***--/--***/****-/"
first_layer = morse_to_numbers(original_code)
print(f"第一层解码结果: {first_layer}")
输出示例 :
第一层解码结果: 4194418141634192622374
3. 第二层:手机键盘映射解码
获得数字串后,我们需要模拟传统手机键盘的字母映射。2009年常见的手机键盘布局如下:
| 数字 | 对应字母 |
|---|---|
| 2 | ABC |
| 3 | DEF |
| 4 | GHI |
| 5 | JKL |
| 6 | MNO |
| 7 | PQRS |
| 8 | TUV |
| 9 | WXYZ |
3.1 构建手机键盘映射表
PHONE_KEYMAP = {
'2': ['A', 'B', 'C'],
'3': ['D', 'E', 'F'],
'4': ['G', 'H', 'I'],
'5': ['J', 'K', 'L'],
'6': ['M', 'N', 'O'],
'7': ['P', 'Q', 'R', 'S'],
'8': ['T', 'U', 'V'],
'9': ['W', 'X', 'Y', 'Z']
}
3.2 数字对解析实现
def phone_keymap_decode(number_str):
# 将数字串分成两位数一组
pairs = [number_str[i:i+2] for i in range(0, len(number_str), 2)]
result = []
for pair in pairs:
num, pos = pair[0], int(pair[1])-1
if num in PHONE_KEYMAP and pos < len(PHONE_KEYMAP[num]):
result.append(PHONE_KEYMAP[num][pos])
else:
result.append('?') # 无效映射处理
return ''.join(result)
执行解码:
second_layer = phone_keymap_decode(first_layer)
print(f"第二层解码结果: {second_layer}")
输出示例 :
第二层解码结果: GZGTGOGXNCS
4. 第三层:QWERTY键盘替换
接下来我们需要处理计算机键盘的字母替换。这种加密方式基于QWERTY键盘布局,将字母替换为它左侧相邻的字母。
4.1 QWERTY键盘布局分析
标准QWERTY键盘的字母部分布局如下:
第一排: Q W E R T Y U I O P
第二排: A S D F G H J K L
第三排: Z X C V B N M
4.2 构建键盘替换映射表
QWERTY_MAP = {
'Q': 'A', 'W': 'B', 'E': 'C', 'R': 'D', 'T': 'E',
'Y': 'F', 'U': 'G', 'I': 'H', 'O': 'I', 'P': 'J',
'A': 'K', 'S': 'L', 'D': 'M', 'F': 'N', 'G': 'O',
'H': 'P', 'J': 'Q', 'K': 'R', 'L': 'S',
'Z': 'T', 'X': 'U', 'C': 'V', 'V': 'W',
'B': 'X', 'N': 'Y', 'M': 'Z'
}
4.3 实现键盘替换解码
def qwerty_decode(encoded_str):
return ''.join([QWERTY_MAP.get(c, c) for c in encoded_str])
执行解码:
third_layer = qwerty_decode(second_layer)
print(f"第三层解码结果: {third_layer}")
输出示例 :
第三层解码结果: OTEOEIOUYVL
5. 第四层:栅栏密码处理
栅栏密码是一种换位密码,通过将字符按特定模式重新排列来加密信息。我们需要实现一个两行的栅栏密码解码器。
5.1 栅栏密码算法实现
def rail_fence_decode(ciphertext, rails=2):
fence = [[] for _ in range(rails)]
rail = 0
direction = 1
# 重建栅栏结构
for _ in ciphertext:
fence[rail].append(None)
rail += direction
if rail == rails-1 or rail == 0:
direction = -direction
# 填充字符到栅栏
index = 0
for i in range(rails):
for j in range(len(fence[i])):
fence[i][j] = ciphertext[index]
index += 1
# 按行读取重建原文
result = []
rail = 0
direction = 1
for _ in range(len(ciphertext)):
if fence[rail]:
result.append(fence[rail].pop(0))
rail += direction
if rail == rails-1 or rail == 0:
direction = -direction
return ''.join(result)
执行解码:
fourth_layer = rail_fence_decode(third_layer)
print(f"第四层解码结果: {fourth_layer}")
输出示例 :
第四层解码结果: OOTUOYEVOLI
6. 第五层:倒序处理与最终解密
最后一层是最简单的倒序处理,将字符串反转即可得到最终明文。
6.1 实现倒序解码
def reverse_decode(encoded_str):
return encoded_str[::-1]
执行最终解码:
final_result = reverse_decode(fourth_layer)
print(f"最终解码结果: {final_result}")
输出示例 :
最终解码结果: ILOVEYOUTOO
7. 完整解密流程整合
现在我们将所有解密步骤整合到一个完整的函数中,实现从原始摩斯密码到最终明文的一键解密。
def decode_love_message(encoded_morse):
# 第一层:摩斯电码转数字
layer1 = morse_to_numbers(encoded_morse)
# 第二层:手机键盘映射
layer2 = phone_keymap_decode(layer1)
# 第三层:QWERTY键盘替换
layer3 = qwerty_decode(layer2)
# 第四层:栅栏密码
layer4 = rail_fence_decode(layer3)
# 第五层:倒序处理
layer5 = reverse_decode(layer4)
return {
'layer1': layer1,
'layer2': layer2,
'layer3': layer3,
'layer4': layer4,
'final_result': layer5
}
完整执行示例:
result = decode_love_message(original_code)
for layer, value in result.items():
print(f"{layer}: {value}")
8. 密码学技巧与优化建议
在实现这个五层解密系统的过程中,我们积累了一些有价值的密码学编程经验:
8.1 字符串处理优化技巧
- 正则表达式预编译 :对于频繁使用的正则模式,预先编译可提升性能
MORSE_SPLIT_PATTERN = re.compile(r'[\s/]+')
- 字典查找优化 :使用
dict.get()方法提供默认值,避免KeyError异常
8.2 密码系统的健壮性增强
- 输入验证 :添加对输入电码格式的检查
def validate_morse_code(morse_str):
return all(c in '*-/' for c in morse_str)
- 错误处理 :为每层解码添加适当的异常处理
try:
layer1 = morse_to_numbers(encoded_morse)
except ValueError as e:
print(f"摩斯解码错误: {e}")
8.3 可扩展的密码系统设计
我们可以将解密流程设计为可配置的管道模式,方便添加或调整解密步骤:
class DecryptionPipeline:
def __init__(self):
self.steps = []
def add_step(self, func):
self.steps.append(func)
def execute(self, input_data):
result = input_data
for step in self.steps:
result = step(result)
return result
# 使用示例
pipeline = DecryptionPipeline()
pipeline.add_step(morse_to_numbers)
pipeline.add_step(phone_keymap_decode)
pipeline.add_step(qwerty_decode)
pipeline.add_step(rail_fence_decode)
pipeline.add_step(reverse_decode)
final_result = pipeline.execute(original_code)
这种设计模式使得密码系统的维护和扩展变得更加灵活,可以轻松应对更复杂的多层加密场景。
更多推荐
所有评论(0)