admin管理员组

文章数量:1574959

本文只谈编程,代码注释部分比较详细,希望大家多多指教!

密文示例ciphertext='OCWYIKOOONIWUGPMXWKTZDWGTSSAYJZWYEMDLBNQAAAVSUWDVBRFLAUPLOOUBFGQHGCSCMGZLATOEDCSDEIDPBHTMUOVPIEKIFPIMFNOAMVLPQFXEJSMXMPGKCCAYKWFZPYUAVTELWHRHMWKBBNGTGUVTEFJLODFEFKVPXSGRSORVGTAJBSAUHZRZALKWUOWHGEDEFNSWMRCIWCPAAAVOGPDNFPKTDBALSISURLNPSJYEATCUCEESOHHDARKHWOTIKBROQRDFMZGHGUCEBVGWCDQXGPBGQWLPBDAYLOOQDMUHBDQGMYWEUIK';

Vigenere.m

clear,clc;%清空变量
%% 第一步:确定秘钥长度
ciphertext='OCWYIKOOONIWUGPMXWKTZDWGTSSAYJZWYEMDLBNQAAAVSUWDVBRFLAUPLOOUBFGQHGCSCMGZLATOEDCSDEIDPBHTMUOVPIEKIFPIMFNOAMVLPQFXEJSMXMPGKCCAYKWFZPYUAVTELWHRHMWKBBNGTGUVTEFJLODFEFKVPXSGRSORVGTAJBSAUHZRZALKWUOWHGEDEFNSWMRCIWCPAAAVOGPDNFPKTDBALSISURLNPSJYEATCUCEESOHHDARKHWOTIKBROQRDFMZGHGUCEBVGWCDQXGPBGQWLPBDAYLOOQDMUHBDQGMYWEUIK';%密文
%重合指数法
length=size(ciphertext);length=length(2);%密文长度为length
N=min(25,length);%循环次数为N,当密文长度<26时,循环次数最大为length
count=zeros(N,2);%count记录每移一次上下重合的字母个数,大小为N*2
ciphertext_temp=ciphertext;%用于比较的中间变量,初始值为ciphertext
for i=1:1:25
    ciphertext_temp=[ciphertext_temp(2:end),ciphertext_temp(1)];%每次向前移一位
    count(i,:)=size(find(ciphertext==ciphertext_temp));%统计上下字母相同的个数
end
count=count(:,2);%取第2列--每次偏移后上下字母的重合数量
key_length=find(count==max(count));%key_length为秘钥长度
%% 第二步:确定秘钥,根据向量之间的夹角来确定
ciphertext=[ciphertext,ones(1,mod(length,key_length))];%如果密文长度不能整除秘钥长度,则在最后加上空格
ciphertext=reshape(ciphertext,key_length,[]);%每一行是由同一凯撒码加密的
key=ones(1,key_length);%key为秘钥
for i=1:1:key_length
    key(i)=Caesar(ciphertext(i,:));%使用Caesar()函数求得每一行的凯撒码
end
%% 第三步:确定明文
for i=1:1:key_length
cipher_temp=ciphertext(i,:);%每一行使用同一个凯撒码
cipher_temp=cipher_temp-'A';%将字母转换为数字,'A'对应0,'Z'对应25
cipher_temp=mod(cipher_temp-key(i),26);%密文->明文,秘钥为key(i)
ciphertext(i,:)=cipher_temp;
end
plaintext=reshape(ciphertext,1,[]);
plaintext(plaintext<0)=[];%删除可能存在的空格
plaintext=plaintext+('A'-0);
plaintext=char(plaintext);%将数字转换为字母

Caesar.m

function key=Caesar(cipher)
cipher=upper(cipher);%将小写字母转换为大写字母
cipher=cipher-'A';%将字母转换为数字,'A'对应0,'Z'对应25
cipher(cipher<0)=[];%删除最后一行可能存在的空格
product=zeros(1,26);%表示每一种实际字母频次表与理论频次表的内积
frequency=zeros(1,26);%表示每一种实际字母频次表
%理论上的字母频次表,百分比
theoryFrequency=[8.19,1.47,3.83,3.91,12.25,2.26,1.71,4.57,7.10,0.14,0.41,3.77,3.34,7.06,7.26,2.89,0.09,6.85,6.36,9.41,2.58,1.09,1.59,0.21,1.58,0.08 ];
theoryFrequency=theoryFrequency./100;%化为小数,便于计算
for i=0:1:25%秘钥的可能值为0--25
    cipher_temp=mod(cipher-i,26);
    for j=0:1:25
        count=size(find(cipher_temp==j));count=count(2);%count表示数字i在cipher_temp中的个数
        frequency(j+1)=count;%frequence中存放的是每一个字母的个数
    end
    frequency=frequency./sum(frequency);%将频次化为频率
    product(i+1)=sum(frequency.*theoryFrequency);%每一种情况下的内积
end
key=find(product==max(product))-1;%key为秘钥
end

运行结果:秘钥key={7 ,14 ,11, 12, 4, 18}

明文:plaintext='HOLMESHADBEENSEATEDFORSOMEHOURSINSILENCEWITHHISLONGTHINBACKCURVEDOVERACHEMICALVESSELINWHICHHEWASBREWINGAPARTICULARLYMALODOROUSPRODUCTHISHEADWASSUNCUPONHISBREASTANDHELOOKEDFROMMYPOINTOFVIEWLIKEASTRANGELANKBIRDWITHDULLGREYPLUMAGEANDABLACKTOPKNOTSOWATSONSAIDHESUDDENLYYOUDONOTPROPOSETOINVESTINSOUTHAFRICANSECURITIES';

本文标签: 密码Vigenmatlab