仿射密码之加解密及破解

【题目】

1) 实现仿射密码,具体要求:

A. 实现仿射密码加密过程,由用户输入密钥,可以对任意输入的明文进行加密;

B. 根据用户输入的加密密钥,自动生成解密密钥,并能对加密密文进行解密;

C. 实现仿射密码破解程序(穷举),能对任意输入的密文进行解密

【实现代码】

# -*- coding: utf-8 -*-
"""
Created on Sun Dec 17 20:03:09 2017
仿射密码加密, 解密, 破解
@author: HP
"""
from string import ascii_lowercase as lowercase
from string import ascii_uppercase as uppercase

frequencyTable = [4, 19, 14, 0, 13, 8, 17, 18, 7, 3, \
                  11, 2, 20, 12, 15, 24, 22, 6, 1, 21, \
                  10, 23, 9, 16, 25]

# 删除预留的标点

#文本过滤
def text_filter (text):
    text = text.lower()
    result = ""
    for i in range(len(text)):
        if lowercase.find(text[i]) != -1:
            result += text[i]
    return result
    
#加密部分
def encryption(plaintext, k1, k2):
    plaintext = text_filter(plaintext)
    result = ""
    for i in range(len(plaintext)):
        index = lowercase.find(plaintext[i])
        c_index = (k1*index+k2)%26
        result += uppercase[c_index]
    return result

#解密部分
def get_inverse(a, b): 
    """
    #求a关于模b的逆元
    """
    if(a==1 and b==0):
        x = 1
        y = 0
        return x, y
    else:
        xx, yy = get_inverse(b, a%b)
        x = yy
        y = xx - a//b*yy
        return x, y

def Decryption(k1, k2, ciphertext):
    k3 = get_inverse(k1, 26)[0]
    result = ""
    for i in range(len(ciphertext)):
        index = uppercase.find(ciphertext[i])
        p_index = k3*(index- k2)%26
        result += lowercase[p_index]
    return result
    
#破解部分
def get_frequencyTable(ciphertext): 
    """
    返回一个列表;
    取得密文的字母频率表, 按字母出现频率从大到小排列, 值为字母对应的索引
    """
    #取得字母频率字典
    count = {}
    for i in range(len(ciphertext)):
        count[ciphertext[i]] = count[ciphertext[i]] + 1 if ciphertext[i] in count else 1

    #把字典转换为列表, 并且对其排序, 最终得到返回值
    items = count.items()
    items_list = [[item[1], item[0]]for item in items]
    items_list1 = sorted(items_list, reverse = True)
    chara_list = [item[1] for item in items_list1]
    return list(map(lambda x: uppercase.index(x),chara_list))
    
# 根据a,b,c,d获取密钥K1
def get_k1(a, b, c, d):
    i = 0
    while True:
        k1 = ( float(a - d - 26 * i) / float(b - c) )
        if k1 < -26 or k1 > 26:
            return None
        if isinstance(k1, int):
            return k1
        i = i + 1
        
def get_abcd(list1, list2):
    list3 = list(map(lambda x, y: [x, y], list1, list2))
    result = []
    for i in range(len(list3)):
        for j in range(i+1, len(list3)):
            result.append(list3[i]+list3[j])
    return result
    
def crack():
    list1 = ['u','v','w']
    list2 = ['x','y','z']
    list22 = list(list2)
    result = []
    count = 0
    while count<6:
        for item in get_abcd(list1, list22):
            k1 = get_k1(*item)
            if k1 is None or gcd(k1, 26) != 1:
                break
            k2 = int(d - c * k1) % 26
            result.append( decryption(Cs, t, k3) )
        if(count%2==1):
            first = list2.pop(0)
            list2.append(first)
            list22 = list(list2)
        else:
            list22[1], list22[2] = list22[2], list22[1]
        count += 1        
    

if __name__ == '__main__':
    ciphertext = input("enter the ciphertext: ")
    print(Decryption(7, 3, ciphertext))



    原文作者:维吉尼亚加密问题
    原文地址: https://blog.csdn.net/sinat_34927324/article/details/79700703
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞