python编程挑战——使用python实现恩格玛机(1)

想起一个好玩的事情,使用python来实现德军在二战时加密的设备——恩格玛机。

那么什么是恩格玛机,他是怎么工作的?这篇文章提供了很详细的说明:

https://www.zhihu.com/question/28397034

请看高票回答。

路一步步走,饭一口口吃,下面,我们也来一步步的实现恩格玛机:

 

chapter 1

用python实现简单的字母替换:

当我输入一串字符串的时候(这串字符串并没有标点符号,只有字母和空格),程序会按照事先设置好的字母替换表,简单的替换掉密码。

如:

abcdefghjiklmnopqrstuvwxyz

qwertyuiopasdfghjklzxcvbnm

那么我输入hello world的时候,它应该自动给我替换成 itssg vgkar

试试看吧!

 

 

代码如下:使用的是string的maketrans方法,你想到了吗?

# -*- coding:utf-8 -*-
# 本代码的目的是通过python实现德军二战时期的密码机:恩格玛
# 首先,第一步是定义一个简单的函数:简单字符替换
import re
import string


def simple_replace(password, replace_word):
    if not type(password) == type(replace_word) == type('a'):
        print('密码必须是字符串!')
        return False
    an = re.match('[a-z\s]+$', password)
    if not an:
        print('字符串只能包含小写字母和空格!')
        return False
    if len(replace_word) != 26:
        print('替换码必须为26个字母!')
        return False
    ori_table = 'abcdefghijklmnopqrstuvwxyz'
    table = str.maketrans(ori_table, replace_word)
    return str.translate(password, table)

a_password = input('请输入明文:')
r_password = 'qwertyuiopasdfghjklzxcvbnm'
print('密文如下:', simple_replace(a_password, r_password))

 

我没有考虑到的是,空格是不能加密的,当时的恩格码机也是没有空格和标点符号的,所以我把代码进行了修改。

# -*- coding:utf-8 -*-
# 本代码的目的是通过python实现德军二战时期的密码机:恩格玛
# 首先,第一步是定义一个简单的函数:简单字符替换
import re
import string


def simple_replace(password, replace_word):
    if not type(password) == type(replace_word) == type('a'):
        print('密码必须是字符串!')
        return False
    an = re.match('[a-z]+$', password)  # 我没有考虑到的是,当时的enigma机是没有空格的,所以这里要求输入的明文也必须是小写字母
    if not an:
        print('字符串只能包含小写字母!')
        return False
    if len(replace_word) != 26:
        print('替换码必须为26个字母!')
        return False
    ori_table = 'abcdefghijklmnopqrstuvwxyz'
    table = str.maketrans(ori_table, replace_word)
    return str.translate(password, table)

a_password = input('请输入明文:')
r_password = 'qwertyuiopasdfghjklzxcvbnm'
print('密文如下:', simple_replace(a_password, r_password))

 但是这里只能实现加密,加第一个转子的时候我再考虑恩格码机的自反属性

好的,更新了,现在我加了一个转子,对旧的代码进行了相应的修改

# -*- coding:utf-8 -*-
# 本代码的目的是通过python实现德军二战时期的密码机:恩格玛
# 首先,第一步是定义一个简单的函数:简单字符替换
import re
import string


def simple_replace(password, replace_word):
    count = len(password)  # 先确定转子需要转动的次数
    new_pass = ''  # 设置一个空字符串准备接收密码
    ori_table = 'abcdefghijklmnopqrstuvwxyz'  # 原始的字符串,用来建立映射表
    for obj in password:  # 开始拆解原字符串
        table = str.maketrans(ori_table, replace_word)  # 建立映射表
        new_obj = str.translate(obj, table)  # 把obj通过映射表转换成new_obj
        new_pass += new_obj  # 返回的密码增加一个new_obj
        replace_word = rotors(replace_word)  # 转子转动
    return new_pass  # 返回新的已经被转子加密的密码

# 单独把判断写成一个函数吧,这样比较好区分


def is_str(password, replace_word):  # 判断的函数
    an = re.match('[a-z]+$', password)  # 我没有考虑到的是,当时的enigma机是没有空格的,所以这里要求输入的明文也必须是小写字母
    if not type(password) == type(replace_word) == type('a'):
        print('密码必须是字符串!')
        return False
    elif not an:
        print('字符串只能包含小写字母!')
        return False
    elif len(replace_word) != 26:
        print('替换码必须为26个字母!')
        return False
    else:
        return True  # 修正了函数的写法,增加了一个返回true的选项

# 然而这并非一个完整版,因为转子还不会转动,我们下面让转子每输入一个字符就转动一次。
# 明显不能输入一次计算一次,所以让转子转动len(明文)次,然后依次处理每个字符就可以了


def rotors(replace_word):  # 转子转动的函数,每调用一次,就把转子前面第一个字母移动到最后
    return replace_word[1:] + replace_word[0]

while True:
    a_password = input('请输入明文:')
    r_password = 'qwertyuiopasdfghjklzxcvbnm'
    if is_str(a_password, r_password):
        print('密文如下:', simple_replace(a_password, r_password))
        break
    else:
        pass

 现在已经可以通过转子来实现动态加密了,!

不信?你运行一下,输入aaaaa试试,会被加密成qwert哈

posted on 2015-12-28 11:41  我家有个小豌豆  阅读(1141)  评论(0)    收藏  举报

导航