playfair加密的Matlab实现

来自信息安全的作业。

使用说明:运行时只需要输入密钥,加密文本以 txt 形式存储当前文件夹的  world.txt(用户自己创建,内容尽量为英文字母)

结果都保存在了 key 类里面,为了简化问题,字母都转换为了大写的。

运行结果示意:

 生成的密钥矩阵:

填充后的原文与密文的对比


% 2019-4-30
clear all;
key.K=input('密钥输入:');
if sum(isletter(key.K))~=length(key.K)   % 先对输入密钥合法性进行判断
    error('输入应为字母!');
end
key.info=textread('world.txt','%s','delimiter','\n');
changed1=88;% 将 X 替换掉相同的字符
changed2=90;   % 替换的备选 Z 字符
key.len=length(key.info);
key.serial=[];           % 记录要加密的文本信息
count=1;
for i=1:key.len           % 先将文本里的所有字母检索出来,保存的是ascii码
    row=char(key.info(i));% 读出来的是double 类型的数据
    for j=1:length(row)
        if isletter(row(j))
            key.serial(count)=(row(j));
            count=count+1;
        end
    end
end
% 编码组的改变,将所有的字母改变为大写
key.K=upper(char(key.K));
key.serial=upper(char(key.serial));
% 剔除K里面的重复字符
key.single=[];
index=1;
len=26;
ascii_begin=64;
list=1:len;
list=[list;zeros(1,len)];
key.Klen=length(key.K);
key.strlen=length(key.serial);
% 去掉密钥中的重复字符串
for i=1:key.Klen   
    if list(2,double(key.K(i))-ascii_begin)==0
        list(2,double(key.K(i))-ascii_begin)=1;
        key.single(index)=key.K(i); % 保存的是ASCII码
        index=index+1;
    elseif list(2,double(key.K(i))-ascii_begin)==1
        continue;
    end
end
key.siglen=index-1;   % 密钥不重复的索引
% 生成m密钥字典
key.matrix=[[1:9],[11:26]]+ascii_begin;   % 将i j视为一个
matrixside=5;
matrixlen=25;
unit_J=74;
unit_I=73;
% key.matrix=reshape([1:25]+ascii_begin,5,5)'
for i=1:key.siglen    % 检索合并后的密钥,去除掉重复性的字符
    unit=key.single(i);
    if unit==unit_J   % 将中间的 i 与 j 合并起来
        unit=unit_I;
    end
    n=find(unit==key.matrix);
    key.matrix(i+1:n)=key.matrix(i:n-1);% 排序直接位移
    key.matrix(i)=unit;
end
% 利用密钥字典完成对文章的加密;
key.matrix=reshape(key.matrix,matrixside,matrixside)';
key.demo=[];
index=1;i=1;
while (i<=key.strlen)    % 完成字符的预分配
    if i==key.strlen
        key.demo(index)=key.serial(i);
        break;
    end
    if (i<key.strlen)
        if (key.serial(i)==key.serial(i+1))
            key.demo(index)=key.serial(i);
            index=index+1; 
            if key.serial(i)~= changed1
                key.demo(index)=changed1;
                index=index+1;
            else
                key.demo(index)=changed2;    % 解码复杂
                index=index+1;
            end
        else
            key.demo(index)=key.serial(i);
            index=index+1;
            key.demo(index)=key.serial(i+1);
            index=index+1;
            i=i+1;
        end
    end
    i=i+1;
end
% 补齐长度 将源信息进行保留,操作复制的信息
key.copy=double(key.demo);
key.strlen=length(key.demo);
key.coding=[];% 记录加密结果
index=1;
if mod(key.strlen,2)==1     % 使整个序列为偶数
    key.strlen=key.strlen+1;
    key.copy=[key.copy,changed1];
end
% 密码加密
for j=1:2:key.strlen
    if key.copy(j)==unit_J  % 先完成i j的判断
        key.copy(j)=unit_I;
    end
    if key.copy(j+1)==unit_J
        key.copy(j+1)=unit_I;
    end
%     if (key.copy(j)==key.copy(j+1))&(key.copy(j)~=changed1)
%         key.copy(j+1)=changed1;
%     elseif (key.copy(j)==key.copy(j+1))&(key.copy(j)==changed1)
%         % 如果出现重复字符与X 相同使用备选方案
%         key.copy(j+1)=changed2;
%     end
    [row1,column1]=find(key.copy(j)==key.matrix);
    [row2,column2]=find(key.copy(j+1)==key.matrix);   % mod(5,5)=0 !!!  bug
    if (row1==row2) & (column1~=column2)   % 只位于同行,取右边的序列
        if column1+1==matrixside
            key.coding(index)=key.matrix(row1,matrixside);
            index=index+1;
            key.coding(index)=key.matrix(row1,mod(column2+1,matrixside));
            index=index+1;
        elseif column2+1==matrixside
            key.coding(index)=key.matrix(row1,mod(column1+1,matrixside));
            index=index+1;
            key.coding(index)=key.matrix(row1,matrixside);
            index=index+1;
        else     % 只有一个属性相同
            key.coding(index)=key.matrix(row1,mod(column1+1,matrixside));
            index=index+1;
            key.coding(index)=key.matrix(row1,mod(column2+1,matrixside));
            index=index+1;
        end        
    elseif (column1==column2) &(row1~=row2) % 只位于同列,取下边的序列
        if row1+1==matrixside
            key.coding(index)=key.matrix(matrixside,column1);
            index=index+1;
            key.coding(index)=key.matrix(mod(row2+1,matrixside),column1);
            index=index+1;
        elseif row2+1==matrixside
            key.coding(index)=key.matrix(mod(row1+1,matrixside),column1);
            index=index+1;
            key.coding(index)=key.matrix(matrixside,column1);
            index=index+1;
        else      % 只有一个属性相同
            key.coding(index)=key.matrix(mod(row1+1,matrixside),column1);
            index=index+1;
            key.coding(index)=key.matrix(mod(row2+1,matrixside),column1);
            index=index+1;
        end
    else        % 完全不同的现象
        key.coding(index)=key.matrix(row1,column2);
        index=index+1;
        key.coding(index)=key.matrix(row2,column1);
        index=index+1;
    end
end
key.chmatrix=char(key.matrix);
key.match=[char(key.copy);char(key.coding)];
key.rematch=[char(regexp(key.match(1,:),'\w{0,2}','match')),char(ones(key.strlen/2,1)*60),...
    char(ones(key.strlen/2,1)*61),char(ones(key.strlen/2,1)*62),...
    char(regexp(key.match(2,:),'\w{0,2}','match'))];
key.decoding=[];
index=1;
for j=1:2:key.strlen   % 就是对上述过程的一个反变换,注意边界与顺序,解密过程
    [row1,column1]=find(key.coding(j)==key.matrix);
    [row2,column2]=find(key.coding(j+1)==key.matrix);
    if (row1==row2) & (column1~=column2)   % 只位于同行,取右边的序列
        if column1-1==0
            key.decoding(index)=key.matrix(row1,matrixside);
            index=index+1;
            key.decoding(index)=key.matrix(row1,mod(column2-1,matrixside));
            index=index+1; 
                   
        elseif column2-1==0
            key.decoding(index)=key.matrix(row1,mod(column1-1,matrixside));
            index=index+1;  
            key.decoding(index)=key.matrix(row1,matrixside);
            index=index+1;
                    
        else     % 只有一个属性相同
            key.decoding(index)=key.matrix(row1,mod(column1-1,matrixside));
            index=index+1; 
            key.decoding(index)=key.matrix(row1,mod(column2-1,matrixside));
            index=index+1;
                      
        end        
    elseif (column1==column2) &(row1~=row2) % 只位于同列,取下边的序列
        if row1-1==0
            key.decoding(index)=key.matrix(matrixside,column1);
            index=index+1;  
            key.decoding(index)=key.matrix(mod(row2-1,matrixside),column1);
            index=index+1;
                    
        elseif row2-1==0
            key.decoding(index)=key.matrix(mod(row1-1,matrixside),column1);
            index=index+1;
            key.decoding(index)=key.matrix(matrixside,column1);
            index=index+1;
                       
        else      % 只有一个属性相同
            key.decoding(index)=key.matrix(mod(row1-1,matrixside),column1);
            index=index+1; 
            key.decoding(index)=key.matrix(mod(row2-1,matrixside),column1);
            index=index+1;
                     
        end
    else        % 完全不同的现象
        key.decoding(index)=key.matrix(row1,column2);
        index=index+1;
        key.decoding(index)=key.matrix(row2,column1);
        index=index+1;
        
    end
end
key.decoded=[];
index=1;
delete=[];
for i=2:key.strlen-1        % 只完成了对于插入X的信息判断,对于重复性的东西,没弄
    if key.decoding(i)==changed1 && (key.decoding(i-1)==key.decoding(i+1))
        delete(index)=i;
        index=index+1;
    end
end
if (key.decoding(key.strlen)==changed1)
    delete(index)=key.strlen;
end
copy=key.decoding;
copy(delete)=[];
key.decoded=char(copy);

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值