凯撒加密
问题描述:
要求实现用户输入一个数使得26个字母的排列发生变化,例如用户输入3,输出结果:
——DEFGHIJKLMNOPQRSTUVWXYZABC
同时需要支持负数,例如用户输入-3,输出结果:
——XYZABCDEFGHIJKLMNOPQRSTUVW
下面程序中用到的知识点:
Python ASCII码与字符相互转换
https://www.runoob.com/python3/python3-ascii-character.html
Python join()方法
https://www.runoob.com/python/att-string-join.html
代码:
list1 = []
for i in range(65,91):
list1.append(chr(i))
# print(list1)
# # ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
# print(''.join(list1))
# # ABCDEFGHIJKLMNOPQRSTUVWXYZ
n = int(input("请输入一个整数:"))
if n > 0:
for i in range(n%26):
a = list1.pop(0)
list1.append(a)
else:
for i in range(-n%26):
b = list1.pop()
list1.insert(0,b)
print(''.join(list1))
输出:
维吉尼亚加密
问题描述:
理解了上面的凯撒加密,在此基础上,引入Vigenere(维吉尼亚)加密:——当输入明文,根据你输入的密钥匹配明文中每个字母并移位加密。
(PS:我看网上有的是新建一个密钥库,每次明文加密的时候,从密钥库中随机抽取一个密钥进行对明文的加密,这里采用自己输入的密钥进行加密。)
下面的代码来源于网上,这里做一个解读,加深自己的理解
步骤:
①生成一个字母表:
letter_list = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’
②定义Get_KeyList(key)函数,该函数的作用是将你输入的密钥(即字母,先将字母大写,后转为ASCII码,再减去65)转化为0—25之间的数。得到一个密钥列表,里面的数字就是明文中每个字符需要循环遍历的个数
③定义Encrypt(plaintext, key_list)函数,该函数的作用是将你输入的明文,按照你输入的密钥进行加密处理,返回密文。遍历输入明文中的每个字符,按照输入密钥的数字列表进行循环遍历,如若遇到空格、数字等等,就直接添加到密文中。
其中:if 0 == (i % len(key_list)): i = 0是为了若明文的字符数比密钥的列表长度长,进行循环遍历。
④定义Decrypt(ciphertext, key)函数,参考Encrypt(plaintext, key_list)函数,相反的操作。
举例:
加密过程:
首先,输入密钥 juemi,则转化为:
key_list = [9, 20, 4, 12, 8]
输入明文:che tui,you nei gui !
其中,非字母部分,不做修改直接添加到密文中,字母部分,从c开始,按照key_list中的第一个元素9,即在c的ASCII码基础上,加上9。(c的ASCII码为99,99+9=108,108对应的字符为l),以此类推,第一轮超过key_list的元素个数后,初始化索引,接着从key_list第一个元素开始,循环遍历。
最后输出密文:lbi fcr,ssg vnc kgq!
解码过程只是将加密过程进行相反操作即可。
代码:
letter_list = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # 字母表
# 根据输入的key生成key列表
def Get_KeyList(key):
key_list = [] # 该列表中是数字
for ch in key:
# ord():将字母转化为ASCII码
key_list.append(ord(ch.upper()) - 65)
return key_list
# 加密函数
def Encrypt(plaintext, key_list):
ciphertext = ""
i = 0
for ch in plaintext: # 遍历明文
if 0 == (i % len(key_list)):
i = 0
if ch.isalpha(): # 明文是否为字母,如果是,则判断大小写,分别进行加密
if ch.isupper():
ciphertext += letter_list[(ord(ch) - 65 + key_list[i]) % 26]
i += 1
else:
ciphertext += letter_list[(ord(ch) - 97 + key_list[i]) % 26].lower()
i += 1
else: # 如果密文不为字母(空格或者数字之类的),直接添加到密文字符串里
ciphertext += ch
return ciphertext
# 解密函数
def Decrypt(ciphertext, key):
plaintext = ""
i = 0
for ch in ciphertext: # 遍历密文
if 0 == (i % len(key_list)):
i = 0
if ch.isalpha(): # 密文为否为字母,如果是,则判断大小写,分别进行解密
if ch.isupper():
plaintext += letter_list[(ord(ch) - 65 - key_list[i]) % 26]
i += 1
else:
plaintext += letter_list[(ord(ch) - 97 - key_list[i]) % 26].lower()
i += 1
else: # 如果密文不为字母,直接添加到明文字符串里
plaintext += ch
return plaintext
if __name__ == '__main__':
print("加密请按D,解密请按E:")
user_input = input()
while (user_input != 'D' and user_input != 'E'): # 输入合法性判断
print("输入有误!请重新输入:")
user_input = input()
print("请输入密钥:")
key = input()
while (False == key.isalpha()): # 输入合法性判断
print("输入有误!密钥为字母,请重新输入:")
key = input()
key_list = Get_KeyList(key)
if user_input == 'D':
# 加密
print("请输入明文:")
plaintext = input()
ciphertext = Encrypt(plaintext, key_list)
print("密文为:\n%s" % ciphertext)
else:
# 解密
print("请输入密文:")
ciphertext = input()
plaintext = Decrypt(ciphertext, key_list)
print("明文为:\n%s" % plaintext)
输出: