python之普莱费尔密码

初学Python,想把常规的古典密码和现代密码都手写一遍,今天学到普莱费尔密码了,不得不说,还挺费劲的,加密解密搞完了,至于无密钥暴力破解需要爬山算法等内容,先不写,下面直接贴代码,做个纪念

'''
普莱费尔密码加解密
密文和密钥都是25位的
注意输入的内容不能有空格
'''

import string
import math

def keyProcessing(key):
    #处理密钥
    mydict = {}
    mylist = []
    mylist2 = []

    for i in key:
        if i not in mydict:
            mydict[i] = 0
            if mydict[i] == 0:
                mylist.append(i)
        else:
            mydict[i] += 1
    for j in string.ascii_lowercase:
        if j not in mydict and j != 'j':
            mylist.append(j)
    # print(mylist,len(mylist))
    for k in range(5):
        mylist2.append(mylist[0+5*k:5+5*k])
    #p1,p2
    # print(mylist2)

    p_list = []
    return mylist2
def encryption(plaintext):

    p_list = []
    #明文预处理
    for i in plaintext:
        if i == 'j':
            p_list.append('i')
        else:
            p_list.append(i)

    tmp_str_list = []
    for i in range(math.ceil(len(p_list)/2)+1):
        try:
            tmp_list = p_list[0+2*i:2+2*i]
            if tmp_list[0] == tmp_list[1] and tmp_list[0] != 'z':
                tmp_str = tmp_list[0] + 'z' + tmp_list[1]
                tmp_str_list.append(tmp_str)
            elif tmp_list[0] == tmp_list[1] and tmp_list[0] == 'z':
                tmp_str = tmp_list[0] + 'q' + tmp_list[1]
                tmp_str_list.append(tmp_str)
            else:
                tmp_str = tmp_list[0] + tmp_list[1]
                tmp_str_list.append(tmp_str)
        except:
            tmp_str_list.append(p_list[-1])
            break
    len_str = ''.join(tmp_str_list)
    if len(len_str) % 2 != 0:
        if tmp_str_list[-1] != 'z':
            tmp_str_list.append('z')
        else:
            tmp_str_list.append('q')
    len_str = ''.join(tmp_str_list)
    tmp_len_list = []
    for i in range(int(len(len_str)/2)):
        tmp_len_str = len_str[0+2*i:2+2*i]
        tmp_len_list.append(tmp_len_str)
    # print(tmp_len_list)

    #加密过程
    # kp = ''.join(tmp_len_list)
    mylist2 = keyProcessing(plaintext)

    mylist3 = keyProcessing(key)
    mylist5 = []
    for i in mylist3:
        v = ''.join(i)
        mylist5.append(v)
    mylist5 = ''.join(mylist5)
    mylist4 = []
    for i in mylist2:
        v = ''.join(i)
        mylist4.append(v)
    mylist4 = ''.join(mylist4)
    print(f'mylist5为{mylist5}')
    print(f'mylist3为{mylist3}')
    print(f'mylist4为{mylist4}')
    print(f'tmp_len_list为{tmp_len_list}')
    #在同一列 mylist3里面是Key,tmp_len_list里面是明文
    final_list = []
    for i,x,m in zip(tmp_len_list,mylist4,range(len(tmp_len_list))):
        for j,y in zip(mylist3,range(5)):
            #同行
            if i[0] in j and i[1] in j:
                if  mylist5.index(i[0]) % 5 != 4:
                    c1 = mylist5[mylist5.index(i[0])+1]

                else:
                    c1 = mylist3[y][0]
                final_list.append(c1)
                if mylist5.index(i[1]) % 5 != 4:
                    c2 = mylist5[mylist5.index(i[1]) + 1]
                else:
                    c2 = mylist3[y][0]
                final_list.append(c2)
                print(f'第{m}次{i[0], i[1]} 同行被加密为{c1, c2}')
            #同列
            elif mylist5.index(i[0]) % 5 == mylist5.index(i[1]) % 5  :
                c1 = mylist5[(mylist5.index(i[0])+5)%25]
                c2 = mylist5[(mylist5.index(i[1])+5)%25]
                final_list.append(c1)
                final_list.append(c2)
                print(f'第{m}次{i[0],i[1]} 同列被加密为{c1,c2}')
                break
            #对角
            elif mylist5.index(i[0]) % 5 != mylist5.index(i[1]) % 5 and (i[0] not in j and i[1] in j):
                w1 = mylist5.index(i[0])
                w2 = mylist5.index(i[1])
                #废弃的代码
                # if abs(w1 % 5 - w2 % 5) != 1:
                #     p1 = w1 + 2 * (int((w1 % 5 + w2 % 5) / 2) - w1 % 5)
                #     p2 = w2 + 2 * (int((w1 % 5 + w2 % 5) / 2) - w2 % 5)
                # else:
                #     p1 = w1 + w2 % 5 - w1 % 5
                #     p2 = w2 + w1 % 5 - w2 % 5
                # if w1 % 5  > w2 % 5:
                p1 = w1 - (w1 % 5 - w2 % 5)
                p2 = w2 + (w1 % 5 - w2 % 5)

                # else:
                #     p1 = w1 - (w1 % 5 - w2 % 5)
                #     p2 = w2 + w1 % 5 - w2 % 5
                final_list.append(mylist5[p1])
                final_list.append(mylist5[p2])
                print(f'第{m}次{i[0],i[1]} 对角被加密为{mylist5[p1],mylist5[p2]}')

            else:
                continue

    #输出密文
    print('密文为 ' + ''.join(final_list))

def decryption(key,ciphertext):
    w_list = []
    for c,i in zip(ciphertext,range(int(len(ciphertext)/2))):
        w = ciphertext[0 + 2 * i: 2 + 2 * i]
        w_list.append(w)
    k_list = keyProcessing(key)
    print(f'k_list为{k_list}')
    k2_list = []
    for i in k_list:
        v = ''.join(i)
        k2_list.append(v)
    k2_list = ''.join(k2_list)
    print(f'k2_list为{k2_list}')
    p_list = []
    print(f'w_list为{w_list}')
    for i in w_list:
        for j in k_list:
            #同行
            if i[0] in j and i[1] in j:
                if (k2_list.index(i[0])) % 5 == 0:
                    p1 = k2_list[(k2_list.index(i[0]) + 4)]
                else:
                    p1 = k2_list[(k2_list.index(i[0]) - 1)]
                p_list.append(p1)
                if (k2_list.index(i[1])) % 5 == 0:
                    p2 = k2_list[(k2_list.index(i[1]) + 4)]
                else:
                    p2 = k2_list[(k2_list.index(i[1]) - 1)]
                p_list.append(p2)

                print(f'通过密钥把{i[0]},{i[1]}同行解密恢复为{p1},{p2}')
                break
            # 同列
            elif k2_list.index(i[0]) % 5 == k2_list.index(i[1]) % 5 :
                p1 = k2_list[(k2_list.index(i[0]) - 5) % 25]
                p2 = k2_list[(k2_list.index(i[1]) - 5) % 25]
                p_list.append(p1)
                p_list.append(p2)
                print(f'通过密钥把{i[0]},{i[1]}同列解密恢复为{p1},{p2}')
                break
            # 对角
            elif k2_list.index(i[0]) % 5 != k2_list.index(i[1]) % 5 and (i[0] not in j and i[1] in j):
                w1 = k2_list.index(i[0])
                w2 = k2_list.index(i[1])
                # if abs(w1%5 - w2%5) != 1:
                #     p1 = w1 + 2*(int((w1%5 + w2%5)/2) - w1%5)
                #     p2 = w2 + 2*(int((w1%5 + w2%5)/2) - w2%5)
                # else:
                #     p1 = w1 + w2%5 - w1%5
                #     p2 = w2 + w1%5 - w2%5
                # p_list.append(k2_list[p1])
                # p_list.append(k2_list[p2])
                # if w1 % 5 > w2 % 5:
                p1 = w1 - (w1 % 5 - w2 % 5)
                p2 = w2 + (w1 % 5 - w2 % 5)

                # else:
                #     p1 = w1 + (w2 % 5 - w1 % 5)
                #     p2 = w2 - (w2 % 5 - w1 % 5)
                #     print(p1,p2)
                p_list.append(k2_list[p1])
                p_list.append(k2_list[p2])
                print(f'通过密钥把{i[0]},{i[1]}对角解密恢复为{k2_list[p1]},{k2_list[p2]}')
                break
    print(f'明文预处理之后为: ' + ''.join(p_list))

    #最终结果可能为
    p_list.pop(-1)
    print('最终结果可能为[1]: ' + ''.join(p_list))
    p_list.pop(-2)
    print('最终结果可能为[2]: '+''.join(p_list))






if __name__ == '__main__':
    enter = int(input('加密输入0\n解密输入1\n:'))
    #加密
    if enter == 0:
        # plaintext = 'qingyuzhenshuai'
        # key = 'wuyahandsome'
        plaintext = input('请输入明文: ').lower()
        key = input('请输入密钥: ').lower()
        key = key.replace('j','i')
        keyProcessing(key)
        encryption(plaintext)
    #解密
    if enter == 1:
        # key = 'playfair'
        # ciphertext = 'rpvlniayfppbbrrvuglayfpyrbrpvlniayfppbcv'
        ciphertext = input('请输入密文: ').lower()
        key = input('请输入密钥: ').lower()
        key = key.replace('j', 'i')
        decryption(key,ciphertext)

普莱费尔密码是一种简单的替换式密码,也称为凯撒密码的一种变体,它通过字母表偏移固定的位数来加密文本。在C语言中编写普莱费尔密码的完整代码会涉及到几个步骤: 1. 定义一个字符数组,包含所有可能的字母; 2. 编写函数用于获取用户输入的明文、密钥和偏移量; 3. 创建加密和解密函数,分别处理偏移和反偏移的过程; 4. 实现循环处理字符串,处理大小写字母和非字母字符的情况。 下面是一个简单的普莱费尔密码实现示例(假设只考虑小写字母): ```c #include <stdio.h> #include <string.h> char alphabet[26] = "abcdefghijklmnopqrstuvwxyz"; char encrypted[100], decrypted[100]; void encrypt(char *plaintext, int key) { for (int i = 0; plaintext[i]; i++) { if (plaintext[i] >= 'a' && plaintext[i] <= 'z') { char index = plaintext[i] - 'a'; encrypted[i] = alphabet[(index + key) % 26]; } else { encrypted[i] = plaintext[i]; } } } void decrypt(char *ciphertext, int key) { for (int i = 0; ciphertext[i]; i++) { if (ciphertext[i] >= 'a' && ciphertext[i] <= 'z') { char index = ciphertext[i] - 'a'; decrypted[i] = alphabet[(index - key + 26) % 26]; } else { decrypted[i] = ciphertext[i]; } } } int main() { char plain_text[100], key_str[5]; printf("请输入明文:\n"); fgets(plain_text, sizeof(plain_text), stdin); // 移除fgets结尾的换行符 plain_text[strlen(plain_text) - 1] = '\0'; printf("请输入密钥(整数,范围1-25):\n"); scanf("%s", key_str); int key = atoi(key_str); // 加密操作 encrypt(plain_text, key); printf("加密后的文本:\n%s\n", encrypted); // 解密操作 decrypt(encrypted, key); printf("解密后的文本:\n%s\n", decrypted); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值