用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实现简易计算器的示例代码

    接下来我将详细讲解“Python实现简易计算器的示例代码”的完整攻略。这里我的回答将包含以下几个方面: 需求分析:讲解实现简易计算器所需考虑的功能和需求。 代码实现:展示实现简易计算器的示例代码,并解释代码中的主要部分。 代码测试:演示如何对示例代码进行测试,确保其能够正常运行。 示例说明:提供两个示例,介绍如何使用简易计算器进行基本的数学运算。 1. 需求…

    python 2023年5月19日
    00
  • Flask框架学习笔记之消息提示与异常处理操作详解

    Flask框架学习笔记之消息提示与异常处理操作详解 在Flask框架开发过程中,消息提示和异常处理是非常重要的功能。本篇笔记将详细讲解如何在Flask框架中进行消息提示和异常处理的操作。 消息提示 在Flask框架中,可以通过flash()函数来进行消息提示。flash()函数需要传递两个参数:消息内容和消息类别。消息类别常用的有success、info、w…

    python 2023年5月13日
    00
  • Python设计模式中的创建型工厂模式

    一、什么是创建型工厂模式? 创建型工厂模式是一种常见的设计模式,它可以在不直接实例化对象的情况下,通过一个工厂函数或者方法来创建对象,隐藏了对象的创建细节,降低了耦合度,提高了代码的可维护性和可扩展性。工厂模式是一种创建型模式,它定义了一个用于创建对象的接口,让子类决定实例化哪个类。工厂模式可以将一个系统中的所有产品共同的处理方式,抽象成一个接口,从而降低系…

    python 2023年5月20日
    00
  • 在Python中使用NumPy将一个赫米特数列与另一个数列相乘

    下面是在Python中使用NumPy将一个赫米特数列与另一个数列相乘的完整攻略。 准备环境 首先,你需要安装好NumPy库,可以使用以下命令进行安装: pip install numpy 安装完成后,你可以在Python脚本中引入NumPy: import numpy as np 什么是赫米特数列? 赫米特数列是一种具有特殊数学性质的序列,可以用于描述物理学…

    python-answer 2023年3月25日
    00
  • 用Python实现等级划分

    下面是使用Python实现等级划分的完整攻略: 1. 等级划分的概述 等级划分是对数据集进行分类的一种常用方式,通过将数据集划分为多个等级或类别,实现对数据集的管理和使用。在Python中,我们可以使用数值型等序变量或类别型变量中的标称型、序数型变量,对数据集进行等级划分。 2. 使用等序变量实现等级划分 在使用等序变量实现等级划分时,需要将数据集中的值按照…

    python 2023年6月2日
    00
  • 在Python中使用NumPy返回切比雪夫级数系数的一维数组的缩放伴矩阵

    获取切比雪夫级数系数的一维数组可以使用NumPy库中的chebyt函数,生成缩放伴随矩阵可以使用NumPy库中的companion函数。下面是详细的步骤: 导入NumPy库 在代码文件开头执行以下导入语句: import numpy as np 获取切比雪夫级数系数的一维数组 使用NumPy的chebyt函数,可以获取n阶切比雪夫级数的系数,如下所示: n …

    python-answer 2023年3月25日
    00
  • python 字典 按key值大小 倒序取值的实例

    下面是关于“python字典按key值大小倒序取值的实例”的详细攻略: 一、背景介绍 在Python中,字典是一种非常常用的数据结构,它可以通过key来快速地查找对应的value。有时,我们需要按照key的大小排序来获取字典的值,本文将介绍如何使用Python实现字典按key值大小倒序取值。 二、示例1:使用sorted()函数按key排序 sorted()…

    python 2023年5月13日
    00
  • python Windows最新版本安装教程

    Python Windows最新版本安装教程 Python是一种高级编程语言,广泛应用于Web开发,数据科学和人工智能等领域。在Windows上安装Python是学习和使用Python的第一步,本文将介绍如何在Windows上安装Python的最新版本。 步骤一 下载Python安装包 在官网 https://www.python.org/downloads…

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