Python实现:双向循环链表实践(凯撒加密和维吉尼亚加密)

凯撒加密

问题描述:
要求实现用户输入一个数使得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)

输出:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boss-dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值