学习python基础班结束test:凯撒加密法,利用字母移位来加密字母。现在要求实现这样的一个加密和解密的类
一、凯撒加密法原理
利用字母移位来加密字母,空格、标点及特殊字符不加密。
用0~25数字与26个英文字母一一对应,如下图:
这是凯撒密码手动加密工具——加密条,没加密时明文的A与密文A(数字0)是对齐的,如果将明文字母移位4(以下称为**key)后,来加密这条信息“Today”。
上图向右移4位后的对应关系如下:
此时明文中的‘A’移到了数字4的位置,A加密成了E,将明文信息“Today”对照密文对应的字母,结果为“XSHEC”。
解密的话,要先知道**(移位的值),再将明文中的A移到对应的数字上,将密文上的字母与明文对照即可。
以上,就是凯撒加密法的原理了。
下面,利用编程来实现这样的功能。
【思路】有两种方式来编写程序:一是直接利用字母对应的索引取值;二是利用字母对应的ASC码值。总之都是将字母转成对应的数字,再与移位值进行加减,从而实现其加密或解密。
二、利用Python编程来实现凯撒加密法
一)利用字母对应的索引值来编写
【思路】1)只加密字母,要取得明文字母的索引值,首先要定义带26个字母的字母库letters;2)利用find函数在字母库letters中找到对应的索引值;3)索引值加上**就得到了密文的索引值,通过这个索引值在字母库中找到对应的字母;4)因此需要定义一个空字符串来容纳加密后的新信息;5)还有两个问题要处理:加密时索引值和**的和超过26的情况,解密时其差小于零的情况。从上面的图片可以看出,和值超过26时则减掉26(字母库的长度),差值小于零时则加上26即可。
**由于学习python时间尚短,对于类和函数的编写还不是很熟悉,所以我会先写一般的代码,然后再转写成函数和类,这个过程还是很有意思的。
'''CaesarCipher'''
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' #定义字母库
mode = input('请选择模式\n***1—加密***\n***2—解密***\n:')
key = int(input('请输入**(0~25):')) #将输入的字符串转化为整数
message = input('请输入你要处理的信息\n:').upper() #将输入的信息全部转换成大写。如果字母库中是小写字母的话,这里就全部转为小写
new = ''
for i in message:
if i in letters: #如果是字母的话
num = letters.find(i) #在字母库中找到明文字符对应的索引值
if mode == '1':
num += key #加密。即num= num + key
elif mode == '2':
num -= key #解密
if num >= len(letters): #也可将len(letters)改为26,因为字母库长度为26
num = num - len(letters)
elif num < 0:
num = num + len(letters)
new = new + letters[num]
else: #如果不是字母的话
new = new + i
print('结果为:', new)
运行后结果如下:
下面是根据上面代码改写的类:
class CaesarCipher():
'''凯撒密码'''
def encrypt(self, key): #加密,调用时需要传入**
letters ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
result = ''
message = input('在此输入你想加密的信息:').upper() #输入的信息变为大写
for i in message:
if i in letters: #如果字符是字母的话
num = letters.find(i)
num += key
if num >= len(letters): #如果值大于等于26
num =num -len(letters)
result += letters[num]
else: #如果字符不是字母的话,则不转换
result += i
return result
def decrypt(self, key): #解密,调用时需要传入**
letters ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
result = ''
message = input('在此输入你想解密的信息:').upper()
for i in message:
if i in letters:
num = letters.find(i)
num -= key
if num < 0:
num = num + len(letters)
result += letters[num]
else:
result += i
return result
c = CaesarCipher() #实例化
运行结果如下:
二)利用ASC码来编写程序
【思路】和上面一样,只是由于所利用到字母的ASC码值和上面的情况不一样,这里移位后数值可能超过121或小于65(如下图遍历出的26个字母,其大小写各自的ASC码值),而且大小写的ASC码值也不一样。
1)针对移位后的数据可能超出ASC码值的范围,可以采取取余的方式,即移位后的数字除以26取余数。(为什么是26,因为a~z是26个字母呀!)
2)对于大小写的ASC码值不一样,可以如前面的操作,将需要加密或解密的信息全部转成大写或小写;另外一个方法是在代码里增加一条判断语句就可以了。
同样,还是先写一般代码:
mode = input('请选择模式\n***1—加密***\n***2—解密***\n:')
key = int(input('请输入**(0~25):')) #将输入的**字符串转化为整数
message = input('请输入你要处理的信息\n:')
new = ''
for i in message:
if mode == '1':
if i >= 'a' and i <= 'z': #如果字符是小写字母的话
new += chr(ord('a') + (ord(i) - ord('a') + key) % 26)
elif i >= 'A' and i<= 'Z': #如果字符是大写字母的话
new += chr(ord('A') + (ord(i) - ord('A') + key) % 26)
else: #如果字符不是字母的话,则不需要加密
new += i
if mode == '2':
if i >= 'a' and i <= 'z':
new += chr(ord('a') + (ord(i) - ord('a') - key) % 26)
elif i >= 'A' and i<= 'Z':
new += chr(ord('A') + (ord(i) - ord('A') - key) % 26)
else:
new += i
print('结果为:', new)
运行结果如下图:
【自定义函数-1】
def encrypt(key):
new = ''
message = input('请输入你要加密的信息\n:')
for i in message:
if i >= 'a' and i <= 'z':
new += chr(ord('a') + (ord(i) - ord('a') + key) % 26)
elif i >= 'A' and i<= 'Z':
new += chr(ord('A') + (ord(i) - ord('A') + key) % 26)
else:
new += i
return new
def decrypt(key):
new = ''
message = input('请输入你要解密的信息\n:')
for i in message:
if i >= 'a' and i <= 'z':
new += chr(ord('a') + (ord(i) - ord('a') - key) % 26)
elif i >= 'A' and i<= 'Z':
new += chr(ord('A') + (ord(i) - ord('A') - key) % 26)
else:
new += i
return new
运行结果如下:
【自定义函数-2】自动运行的方式,但此时结果的输出不能用return,而要用print函数
def encrypt():
new = ''
message = input('请输入你要加密的信息\n: ')
for i in message:
if i >= 'a' and i <= 'z':
new += chr(ord('a') + (ord(i) - ord('a') + key) % 26)
elif i >= 'A' and i<= 'Z':
new += chr(ord('A') + (ord(i) - ord('A') + key) % 26)
else:
new += i
print('结果为:', new)
print('<<<<<<<<<<<<<\n')
def decrypt():
new = ''
message = input('请输入你要解密的信息\n: ')
for i in message:
if i >= 'a' and i <= 'z':
new += chr(ord('a') + (ord(i) - ord('a') - key) % 26)
elif i >= 'A' and i<= 'Z':
new += chr(ord('A') + (ord(i) - ord('A') - key) % 26)
else:
new += i
print('结果为:', new)
print('<<<<<<<<<<<<<\n')
while True:
key = int(input('请输入**(0~25):'))
if key not in range(0, 26):
print('**超出范围')
break
print('\n****1:加密****\n****2:解密****')
mode = input('请选择:')
if mode == '1':
encrypt()
elif mode == '2':
decrypt()
else:
print('选择有误')
break
运行后结果如下: