本文共 4310 字,大约阅读时间需要 14 分钟。
【题目】
实现维吉尼亚密码算法,具体要求:
A. 实现维吉尼亚密码加密过程,由用户输入密钥,可以对任意输入的明文进行加密;
B. 根据用户输入的密钥,对密文进行解密;
C. 实现维吉尼亚密码的唯密文攻击破解(基于重合互指数方法)
【实现代码】
# -*- coding: utf-8 -*-"""Created on Wed Dec 13 08:17:01 2017@author: HP"""#!/usr/bin/env python"维吉尼亚"from string import ascii_lowercase as lowercase #加密def VigenereEncrypto (p , key) : p = get_trim_text(p) ptLen = len(p) keyLen = len(key) quotient = ptLen // keyLen #商 remainder = ptLen % keyLen #余 out = "" for i in range (0 , quotient) : for j in range (0 , keyLen) : c = int((ord(p[i*keyLen+j]) - ord('a') + ord(key[j]) - ord('a')) % 26 + ord('a')) #global output out += chr (c) for i in range (0 , remainder) : c = int((ord(p[quotient*keyLen+i]) - ord('a') + ord(key[i]) - ord('a')) % 26 + ord('a')) #global output out += chr (c) return out #解密def VigenereDecrypto (output , key) : ptLen = len (output) keyLen = len (key) quotient = ptLen // keyLen remainder = ptLen % keyLen inp = "" for i in range (0 , quotient) : for j in range (0 , keyLen) : c = int((ord(output[i*keyLen+j]) - ord('a') - (ord(key[j]) - ord('a'))) % 26 + ord('a')) #global input inp += chr (c) for i in range (0 , remainder) : c = int((ord(output[quotient*keyLen + i]) - ord('a') - (ord(key[i]) - ord('a'))) % 26 + ord('a')) #global input inp += chr (c) return inp def get_trim_text(text): text = text.lower() trim_text = '' for l in text: if lowercase.find(l) >= 0: trim_text += l return trim_text #计算重合指数def get_coincidence_index(text): text = get_trim_text(text) length = len(text) letter_stats = [] for l in lowercase: lt = {} count = text.count(l) lt[l] = count letter_stats.append(lt) index = 0 for d in letter_stats: v = list(d.values())[0] index += (float(v)/length) ** 2 return index #计算和0.067的差距大小 def get_var(data, mean=0.067): if not data: return 0 var_sum = 0 for d in data: var_sum += (d - mean) ** 2 return float(var_sum) / len(data)#求秘钥长度def get_key_length(text): # assume text length less than 26 text = get_trim_text(text) group = [] for n in range(1, len(text)+1): group_str = ['' for i in range(n)] for i in range(len(text)): l = text[i] for j in range(n): if i % n == j: group_str[j] += l group.append(group_str) var_list = [] length = 1 for tex in group: data = [] for t in tex: index = get_coincidence_index(t) data.append(index) var_list.append([length, get_var(data)]) length += 1 var_list = sorted(var_list, key=lambda x: x[1]) print(var_list) return [v[0] for v in var_list[:int(n/2)+1]] #var_list[0][0] # 统计字母频度def countList(lis): li = [] alphabet = [chr(i) for i in range(97,123)] for c in alphabet: count = 0 for ch in lis: if ch == c: count+=1 li.append(float(count)/len(lis)) return li# 根据密钥长度将密文分组def textToList(text,length): text = get_trim_text(text) textMatrix = [] row = [] index = 0 for ch in text: row.append(ch) index += 1 if index % length ==0: textMatrix.append(row) row = [] textMatrix.append(row) return textMatrix # 获取密钥def getKey(text,length): text = get_trim_text(text) key = [] # 定义空白列表用来存密钥 alphaRate =[0.08167,0.01492,0.02782,0.04253,0.12705,0.02228,0.02015,0.06094,\ 0.06996,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,\ 0.0009,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.0015,0.01974,0.00074] matrix = textToList(text,length) for i in range(length): w = [row[i] for row in matrix if len(row) > i] #获取每组密文 li = countList(w) powLi = [] #算乘积 for j in range(26): Sum = 0.0 for k in range(26): Sum += alphaRate[k]*li[k] powLi.append(Sum) li = li[1:]+li[:1]#循环移位 Abs = 100 ch = '' for j in range(len(powLi)): if abs(powLi[j] -0.065546)
转载地址:http://jhaii.baihongyu.com/