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哈
浙公网安备 33010602011771号