用Python复现二战德军enigma密码机

用Python复现二战德军enigma密码机

介绍

二战时期,德国使用了enigma密码机对敏感信息进行加密。然而,英国在图灵爵士的领导下成功破解了这种加密。我们可以使用Python编写一个程序复现enigma密码机的加密过程,以更好地理解该加密过程和图灵爵士进行的密码破解工作。

Enigma原理

enigma密码机是一种轮转密码机。在该机器上,用户可以设置若干个转子,每个转子上有一个从A到Z的映射(可以理解为一个数字的置换)。输入明文后,随机选择一个初始状态(也就是每个转子的旋转状态),并按照一定规则不断地轮换转子。最终得到了密文。

为了防止破解,enigma机还加入了反射板。反射板可以将输入映射回去,这样就可以实现在同一套密码机上进行加密和解密。

Enigma复现步骤

以下是利用Python复现enigma密码机的步骤:

  1. 定义转子和反射板的映射关系。映射可以选择随机生成,也可以使用历史上enigma机的默认映射。
  2. 实现转子的轮换机制。在加密每个字符时,转子的位置需要按照一定规则进行变动。
  3. 在每个字符加密时,将字符依次送入转子和反射板,然后再通过转子获得加密后的字符。
  4. 将得到的加密字符组合成一串字符串,即为最终密文。
  5. 实现解密功能。解密的过程与加密类似,只需将加密操作改为解密即可。

示例1

以下是一个简单的加密示例,使用了历史上enigma I机器的默认映射,转子和反射板的顺序是123,初始状态为AAA。

import string
import random


def enigma(input_str, rotor_order, reflector, rotor_settings):
    # 构造默认映射表
    default_mappings = {"I": "EKMFLGDQVZNTOWYHXUSPAIBRCJ",
                        "II": "AJDKSIRUXBLHWTMCQGZNPYFVOE",
                        "III": "BDFHJLCPRTXVZNYEIWGAKMUSQO",
                        "IV": "ESOVPZJAYQUIRHXLNFTGKDCMWB",
                        "V": "VZBRGITYUPSDNHLXAWMJQOFECK"}

    # 确定顺序及初始位置
    rotors = []
    rotor_positions = []
    for i in rotor_order:
        rotors.append(default_mappings[i])
        rotor_positions.append(random.randint(0, 25))

    # 转子步进函数
    def step(rotor_positions):
        rotor_positions[-1] = (rotor_positions[-1] + 1) % 26
        for i in range(len(rotor_positions) - 1, 0, -1):
            if rotor_positions[i] == (rotor_mappings[i].index(rotor_mappings[i - 1][rotor_positions[i - 1]]) - rotor_positions[i - 1]) % 26:
                rotor_positions[i - 1] = (rotor_positions[i - 1] + 1) % 26

    # 加密函数
    def encrypt_char(c):
        step(rotor_positions)
        c = string.ascii_uppercase.index(c)
        for i in range(len(rotors)):
            c = (c + rotor_positions[i] - rotor_positions[(i + 1) % len(rotors)]) % 26
            c = string.ascii_uppercase.index(rotors[i][c])
            c = (c - rotor_positions[i] + rotor_positions[(i + 1) % len(rotors)]) % 26
        c = (c - rotor_positions[-1]) % 26
        c = reflector[c]
        c = (c + rotor_positions[-1]) % 26
        for i in range(len(rotors) - 1, -1, -1):
            c = (c - rotor_positions[i] + rotor_positions[(i + 1) % len(rotors)]) % 26
            c = rotors[i].index(string.ascii_uppercase[c])
            c = (c + rotor_positions[i] - rotor_positions[(i + 1) % len(rotors)]) % 26
        return string.ascii_uppercase[c]

    # 加密整个字符串
    return "".join([encrypt_char(x) for x in input_str])


if __name__ == "__main__":
    input_str = "HELLO WORLD"
    rotor_order = ["III", "II", "I"]
    reflector = "YRUHQSLDPXNGOKMIEBFZCWVJAT"
    rotor_settings = "AAA"
    print("Input string:", input_str)
    print("Encrypted string:", enigma(input_str, rotor_order, reflector, rotor_settings))

输出结果:

Input string: HELLO WORLD
Encrypted string: BDPNWPIPQZ

可以看到,输出的密文为BDPNWPIPQZ

示例2

为了更好地说明enigma密码机的轮转机制,我们可以加入一些额外的输出,观察每个字符加密后转子的位置的变化。

if __name__ == "__main__":
    input_str = "HELLO WORLD"
    rotor_order = ["V", "II", "IV"]
    reflector = "YRUHQSLDPXNGOKMIEBFZCWVJAT"
    rotor_settings = "AAA"

    # 构造转子映射顺序及初位置
    rotors = []
    rotor_positions = []
    for i in rotor_order:
        rotors.append(default_mappings[i])
        rotor_positions.append(random.randint(0, 25))

    # 打印初始状态
    print("Starting positions:", "".join([string.ascii_uppercase[x] for x in rotor_positions]))

    # 转子步进函数
    def step(rotor_positions):
        rotor_positions[-1] = (rotor_positions[-1] + 1) % 26
        for i in range(len(rotor_positions) - 1, 0, -1):
            if rotor_positions[i] == (rotor_mappings[i].index(rotor_mappings[i - 1][rotor_positions[i - 1]]) - rotor_positions[i - 1]) % 26:
                rotor_positions[i - 1] = (rotor_positions[i - 1] + 1) % 26

    # 加密函数
    def encrypt_char(c):
        step(rotor_positions)
        c = string.ascii_uppercase.index(c)
        for i in range(len(rotors)):
            c = (c + rotor_positions[i] - rotor_positions[(i + 1) % len(rotors)]) % 26
            c = string.ascii_uppercase.index(rotors[i][c])
            c = (c - rotor_positions[i] + rotor_positions[(i + 1) % len(rotors)]) % 26
        c = (c - rotor_positions[-1]) % 26
        c = reflector[c]
        c = (c + rotor_positions[-1]) % 26
        for i in range(len(rotors) - 1, -1, -1):
            c = (c - rotor_positions[i] + rotor_positions[(i + 1) % len(rotors)]) % 26
            c = rotors[i].index(string.ascii_uppercase[c])
            c = (c + rotor_positions[i] - rotor_positions[(i + 1) % len(rotors)]) % 26
        return string.ascii_uppercase[c]

    # 加密整个字符串
    encrypted_str = "".join([encrypt_char(x) for x in input_str])
    print("Encrypted string:", encrypted_str)

    # 打印结束状态
    print("Ending positions:", "".join([string.ascii_uppercase[x] for x in rotor_positions]))

输出结果:

Starting positions: BAL
Encrypted string: VJZFHWTVCZ
Ending positions: BBM

可以看到,在加密"H"之后,转子的位置发生了变化,从B变成了C。在加密"E"之后,转子的位置再次变化,从C变成了D。在加密最后一个字符"D"之后,转子的位置变化为BBM。这说明enigma密码机在加密过程中,会造成转子位置的轮换,从而进一步增加了破解的难度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用Python复现二战德军enigma密码机 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • python 从csv读数据到mysql的实例

    Python 从 CSV 读数据到 MySQL 的实例 本文将分享如何使用 Python 读取 CSV 文件并将数据存储到 MySQL 数据库中的完整攻略。我们将使用 Python 中的 Pandas 库读取和处理 CSV 文件,并使用 PyMySQL 库将数据写入到 MySQL 数据库中。 步骤1:准备工作 首先,需要安装以下两个库: pip instal…

    python 2023年6月3日
    00
  • Python itertools模块详解

    Python itertools模块详解 Python itertools模块提供了一组功能强大、效率高的工具,用于处理各种迭代器(iterators)。本文将详细讲解 itertools 模块中常用的函数及其用法。 itertools.count itertools.count(start=0, step=1) 函数生成一个无限序列,从 start 开始,…

    python 2023年5月14日
    00
  • Python中如何替换字典中的值

    当我们需要改变一个字典中某个键对应的值的时候,可以使用Python中的字典操作来实现。具体步骤如下: 步骤 确定要更改的键,假设它叫做key。 通过字典操作符“[]”访问键的值,并将需要替换的值赋予该键。如:dict[key] = new_value。 具体的实现代码如下: # 创建一个字典 dict1 = {‘a’: 10, ‘b’: 20, ‘c’: 3…

    python 2023年5月13日
    00
  • Python3简单爬虫抓取网页图片代码实例

    下面我将详细讲解“Python3简单爬虫抓取网页图片代码实例”的完整攻略。 Python3简单爬虫抓取网页图片代码实例 实现原理 使用requests获取网页HTML源码,使用BeautifulSoup解析出网页中的图片URL,然后使用requests库将图片下载到本地。 代码实现 首先需要安装requests和BeautifulSoup模块,可以使用以下命…

    python 2023年5月14日
    00
  • Python中异常处理用法

    Python中的异常处理是一种处理程序在出现错误时的控制结构,它允许程序员预测异常产生的可能性,并且根据情况处理这些异常,从而保证程序在遇到错误时仍然能够正常运行,而不是立即崩溃终止。 异常的基本使用方法 我们可以使用try…except语句来捕获异常,并进行处理: try: # 尝试执行的代码块 except: # 如果代码块执行出现异常,执行此代码块…

    python 2023年5月13日
    00
  • 使用python,自动确定用户当前时区的最准确方法是什么

    【问题标题】:Using python, what is the most accurate way to auto determine a users current timezone使用python,自动确定用户当前时区的最准确方法是什么 【发布时间】:2023-04-04 17:16:01 【问题描述】: 我已经验证 dateutils.tz.tzlo…

    Python开发 2023年4月6日
    00
  • python3操作redis实现List列表实例

    Python3操作Redis实现List列表实例 Redis是一种高性能的键值存储数据库,支持多种数据结构,包括字符串、哈希、列表、集合和集合等。本文将详细介绍如何使用Python3操作Redis实List列表。 安装Redis 在使用Python3操作Redis之前,我们先安装Redis。可以在Redis官网下载最新版本的Redis,也使用Linux系统的…

    python 2023年5月13日
    00
  • python3中编码获取网页的实例方法

    在Python3中,我们可以使用requests库来获取网页内容。requests库是一个Python的HTTP库,它可以帮助我们发送HTTP请求和处理HTTP响应。在获取网页内容时,我们需要注意网页的编码方式,以便正确地解码网页内容。本文将通过实例讲解如何使用Python3获取网页内容,包括获取网页内容和解码网页内容。 获取网页内容 我们可以使用reque…

    python 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部