利用凯撒密码的原理对字符串进行加密

  1. 用户分别输入姓名和学号(数字);
  2. 利用学号得到密钥,规则是:学号中所有数字之和与学号长度的余数作为密钥,如果余数为0,则将密钥设置为9;需要处理用户输入的密码中含有非数字字符的情况,对于非数字字符,不需要加入数字之和中,但是要计入长度。
  3. 利用密钥对姓名进行加密后输出加密后的字符串,加密规则是:
    • 仅对汉字进行加密,其他字符保留原始字符;
    • 对于某个汉字,加密后的字符为在unicode表中当前字符位置+密钥后的位置所对应的字符(凯撒密码);
    • 如果加上密钥后的位置超出了汉字的范围,则从最小的汉字开始,例如:已知最小的汉字是“一”,紧跟其后的汉字是"丁","最大的汉字是“龥",如果密钥是1,当前汉字为"一"时,加密后的汉字应该是"丁";当前为最大的汉字“龥”,则加密后的汉字应该是最小的汉字“一”,以此类推。
  4. 要求用户再次输入解密的密码(学号),根据用户输入的密码,对加密后的字符串进行解密。如果解密后的字符串和原始字符串(姓名)不一致,要求用户重新输入,并提示用户:"解密的密码错误,请重新输入"。直到用户输入的密码能正确用于解密(即解密后的字符串和原始字符串一致),显示解密后的姓名,并结束程序。

好像有个漏洞,比如如果用户输入学号是12,秘钥是1,则解密的时候即使输入121也能解开,因为秘钥也是1

def key(stu_id):
    s=0
    for i in stu_id:
        if i.isnumeric():
            s+=int(i)
    k=s%len(stu_id)
    return 9 if k==0 else k

def trans(name, k, encode=True):
    ename=''
    for i in name:
        if 19968<=ord(i)<=40869:
            if encode:
                new=ord(i)+k
                if new>40869:new-=20902
            else:
                new=ord(i)-k
                if new<19968:new+=20902
            ename+=chr(new)
        else:
            ename+=i
    return ename

name=input('姓名:')
stu_id=input('学号:')
s=0
k = key(stu_id)
ename=trans(name,k)

while True:
    de_id=input('请输入解密的密码:')
    k=key(de_id)
    new_name=trans(ename,k,False)
    if new_name==name:
        print(name)
        break
    else:
        print('解密的密码错误,请重新输入')