1.实验目的:
(1)了解经典加密算法对于同学们理解现代密码学的基本思想有很大帮助。
(2)在本实验中,采用MATLAB实现playfair加密。
2.实验设备:
Win10系统、MATLAB软件
3.实验原理:
(1)多字母组密码,提供双字母替代模式
(2)英国科学家Charles Wheatstone 在1854年提出的。
(3)核心是基于密钥的5x5矩阵,例如,基于密钥MONARCHY:
M | 0 | N | A | R |
C | H | Y | B | D |
E | F | G | I/J | K |
L | P | Q | S | T |
U | V | W | X | Z |
(4)矩阵填充方法:
首先将密钥词(去掉重复字母)从左至右、从上至下填在矩阵格子里,再将剩余的字母按字母表的顺序从左至右、从上至下填在矩阵剩下的格子里。字母I和J暂且当做一个字母。
(5)Playfair加密规则:
(a)如果字母对中两个字母相同,加入填充字母,如X“balloon”编码为 "ba lx lo on"。
(b)如果字母对中字母位于矩阵的同一行,则每一字母用其右边字母替代,“or”编码为“NM"。
(c)如果字母对中字母位于矩阵的同一列,则每一字母用其下边字母替代“mu”编码为“CM“。
(d)其他字母对中字母按矩阵对角线字母替代,“hs” 编码为 “BP”。“ea” 编码为 “IO”。
注:每两个字母为一组,当输入明文字母不是偶数个时,补Z。
代码
playfairtest.m
clear all;
clc;
plain_p=input('请输入原文:','s');%plain为原文,cipher为加密后的密文
plain=char(plain_p)-32;%密文字母转数字
cipher=Playfair(plain);
fprintf('密文为:');
disp(cipher);
DECODE=Playfairdecode(cipher);
fprintf('解密后得到的原文为:');
disp(DECODE);
Playfairdecode.m
function plain=Playfairdecode(cipher)%plain 为原文,cipher为加密后的密文
Ke=['M','O','N','A','R';
'C','H','Y','B','D';
'E','F','G','I','K';
'L','P','Q','S','T';
'U','V','W','X','Z'];
L=length(cipher);
for i=1:L
for j=1:5
for k=1:5
if cipher(i)==Ke(j,k)
m(i)=j;%记下第一个字符所在的行为m
n(i)=k;%记下第一个字符所在的列为n
end
end
end
end
t=1;
for i=1:2:L-1
% if m(i)==m(i+2)&&n(i)=n(i+2)%如果两个字母相同
% plain(t)=Ke(m(i),n(i));
% plain(t+1)=Ke(m(i),n(i));
% i=i+1;
% end
if m(i)==m(i+1)&&n(i)~=n(i+1)%如果两个字母同行
if n(i+1)~=1&&n(i)~=1%如果两个字母都不在第5列
n(i+1)=n(i+1)-1;
n(i)=n(i)-1;
elseif n(i)==1%如果第一个字符在第5列
n(i)=5;
n(i+1)=n(i+1)-1;
elseif n(i+1)==1%如果第二个字符在第5列
n(i+1)=5;
n(i)=n(i)-1;
end
plain(t)=Ke(m(i),n(i));
plain(t+1)=Ke(m(i+1),n(i+1));
t=t+2;
elseif m(i)~=m(i+1)&&n(i)==n(i+1)%如果两个字母同列
if m(i+1)~=1&&m(i)~=1%如果两个字符都不在第五行
m(i+1)=m(i+1)-1;
m(i)=m(i)-1;
elseif m(i)==1
m(i)=5;
m(i+1)=m(i+1)-1;
elseif m(i+1)==1
m(i+1)=5;
m(i)=m(i)-1;
end
plain(t)=Ke(m(i),n(i));
plain(t+1)=Ke(m(i+1),n(i+1));
t=t+2;
else%如果两个字符不同行不同列
plain(t)=Ke(m(i),n(i+1));
plain(t+1)=Ke(m(i+1),n(i));
t=t+2;
end
end
end
Playfair.m
function cipher=Playfair(plain)%plain 为原文,cipher为加密后的密文
Ke=['M','O','N','A','R';
'C','H','Y','B','D';
'E','F','G','I','K';
'L','P','Q','S','T';
'U','V','W','X','Z'];
L=length(plain);
% if mod(L,2)==1%如果字符不是2的整数倍
% plain(L+1)='Z';
% plain(L)=plain(L);
% end
% L=L+1;
for i=1:L
for j=1:5
for k=1:5
if plain(i)==Ke(j,k)
m(i)=j;%记下第一个字符所在的行为m
n(i)=k;%记下第一个字符所在的列为n
end
end
end
end
t=1;
for i=1:2:L-1
if m(i)==m(i+1)&&n(i)==n(i+1)%如果两个字符相同
cipher(t)=Ke(m(i),n(i));
cipher(t+1)='X';
cipher(t+2)=Ke(m(i),n(i));
% t=t+3;
elseif m(i)==m(i+1)&&n(i)~=n(i+1)%如果两个字母同行
if n(i+1)~=5&&n(i)~=5%如果两个字母都不在第5列
n(i+1)=n(i+1)+1;
n(i)=n(i)+1;
elseif n(i)==5%如果第一个字符在第5列
n(i)=1;
n(i+1)=n(i+1)+1;
elseif n(i+1)==5%如果第二个字符在第5列
n(i+1)=1;
n(i)=n(i)+1;
end
cipher(t)=Ke(m(i),n(i));
cipher(t+1)=Ke(m(i+1),n(i+1));
t=t+2;
elseif m(i)~=m(i+1)&&n(i)==n(i+1)%如果两个字母同列
if m(i+1)~=5&&m(i)~=5%如果两个字符都不在第五行
m(i+1)=m(i+1)+1;
m(i)=m(i)+1;
elseif m(i)==5
m(i)=1;
m(i+1)=m(i+1)+1;
elseif m(i+1)==5
m(i+1)=1;
m(i)=m(i)+1;
end
cipher(t)=Ke(m(i),n(i));
cipher(t+1)=Ke(m(i+1),n(i+1));
t=t+2;
else%如果两个字符不同行不同列
cipher(t)=Ke(m(i),n(i+1));
cipher(t+1)=Ke(m(i+1),n(i));
t=t+2;
end
end
end