五层加密的浪漫:用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)

这种设计模式使得密码系统的维护和扩展变得更加灵活,可以轻松应对更复杂的多层加密场景。

更多推荐