MATLAB实现维吉尼亚密码加解密

程序下载链接:https://download.csdn.net/download/m0_56241309/87457176

实验题目:维吉尼亚密码

一、实验目的

实验环境: Windows 11操作系统;Matlab2019b

实现目标:实现维吉尼亚密码加解密;

实现加密解密交互界面;

实现加密解密关键步骤信息输出。

二、方案设计

1. 加密过程

  1. 首先初始化维吉尼亚密码表,将整张密码表先暂存,为接下来的加密工作做好准备

  1. 随后获取明文字符串,将字符串中的空格全部删除,并将字符串大写化

  1. 对明文预处理结束后,获取密钥,将密钥字符大写化。为了接下来的加密工作,首先将密钥字符串不断循环至与明文字符串等长(也可以使用模运算的方式),确定好明文字符与密钥字符之间的一一对应关系

  1. 确定好明文字符与密钥字符之间的对应关系后,便可以开始加密。明文字符的在字母表中的位置相当于横坐标,密钥字符在字母表中的位置相当于纵坐标。横纵坐标在此前暂存的维吉尼亚密码表中唯一地确定一个密文字符。依次对明文字符使用该种方式进行加密处理,将得到的密文字符拼接后便得到最终的密文字符串。

2. 解密过程

  1. 同样的道理,解密时需要初始化维吉尼亚密码表,先将整张密码表暂存,待接下来的解密步骤使用

  1. 随后获取密文字符串,由于密文字符串已不存在小写字符以及空格,因此无需进一步处理

  1. 接下来获取密钥,将密钥字符大写化。为了接下来的解密工作,首先将密钥字符串不断循环至与密文字符串等长(也可以使用模运算的方式),确定好密文字符与密钥字符之间的一一对应关系

  1. 确定好密文字符与密钥字符之间的对应关系后,便可以开始解密。首先确定每个对应位置的密文字符在字母表中的位置,将其作为纵坐标y。随后在维吉尼亚密码表中找到对应的第y行,在该行中寻找与这个密文字符相对应的明文字符的位置x。于是可以确定明文字符为在字母表中的第x个字符。每一位都使用该种方式进行解密处理,将得到的明文字符进行拼接后便可以得到最终的明文字符串。

3. 信息输出

  1. 设置两个信息输出函数,分别实现加密界面和解密界面的信息输出

4. 交互界面

  1. 基于Matlab2019b中的mlapp编程实现

三、方案实现

1. 加密过程

介绍:加密按钮EnButtom回调函数

function EnButtonPushed(app, event)
            ifstrcmp(app.Plaintext_En.Value,'')
                logRefresh_func_En(app,'请输入明文信息');
                return
            end
            
            ifstrcmp(app.Key_En.Value,'')
                logRefresh_func_En(app,'请输入密钥');
                return
            end
            %初始化维吉尼亚密码表
            app.alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            %初始化密码表
            fbar=waitbar(0,'初始化密码表');
            pause(0.3)
            for i=1:26
                waitbar(i/26,fbar,'初始化中,请稍后');
                pause(0.01)
                for j=1:26
                    app.Mat(i,j)=' ';
                end
            end
            waitbar(1,fbar,'密码表初始化完成');
            pause(0.3)
            logRefresh_func_En(app,'密码表初始化完成')
            %填充26*26的密码表
            waitbar(0,fbar,'密码表填充');
            pause(0.3)
            cat='';
            for i=1:26
                waitbar(i/26,fbar,'密码表填充中,请稍后');
                pause(0.01)
                if i==1
                    app.Mat(i,:)=app.alphabet;
                else
                    app.Mat(i,:)=strcat(app.alphabet(i:end),cat);
                end
                cat=strcat(cat,app.alphabet(i));
            end
            waitbar(1,fbar,'密码表填充完成');
            pause(0.3)
            logRefresh_func_En(app,'密码表填充完成')
            Key_text=upper(app.Key_En.Value);
            Plaintext=app.Plaintext_En.Value;
            Plaintext=upper(Plaintext);
            waitbar(0,fbar,'明文字符串处理中,请稍后');
            pause(0.3)
            %删除明文中的空格
            Bridge='';
            for i=1:length(Plaintext)
                waitbar(i/length(Plaintext),fbar,'明文字符串处理中,请稍后');
                pause(0.01)
                ifPlaintext(i)==' '
                    continue
                else
                    Bridge=strcat(Bridge,Plaintext(i));
                end
            end
            waitbar(0,fbar,'明文字符串处理完毕');
            pause(0.3)
            logRefresh_func_En(app,'明文字符串处理完毕')
            Plaintext=Bridge;
            keytext=Plaintext;
            %确定好映射关系
            for i=1:length(Plaintext)
                %判断该字符对应着密钥中的哪一个字符
                if mod(i,length(Key_text))==0
                    keytext(i)=Key_text(length(Key_text));
                else
                    keytext(i)=Key_text(mod(i,length(Key_text)));
                end
            end
            waitbar(0,fbar,'加密中,请稍后');
            pause(0.3)
            %开始加密
            Ciphertext='';
            for i=1:length(Plaintext)
                waitbar(i/length(Plaintext),fbar,'加密中,请稍后');
                pause(0.01)
                x=find(app.alphabet==Plaintext(i));
                y=find(app.alphabet==keytext(i));
                Ciphertext=strcat(Ciphertext,app.Mat(x,y));
            end
            waitbar(1,fbar,'加密完成');
            pause(0.3)
            close(fbar)
            logRefresh_func_En(app,'加密完成')
            app.Crypt_En.Value=Ciphertext;
            app.Crypt_De.Value=Ciphertext;
end

2. 解密过程

介绍:解密按钮DeButtom回调函数

function DeButtonPushed(app, event)
            ifstrcmp(app.Crypt_De.Value,'')
                logRefresh_func_De(app,'请输入密文信息');
                return
            end
            
            ifstrcmp(app.Key_De.Value,'')
                logRefresh_func_De(app,'请输入密钥');
                return
            end
            %初始化维吉尼亚密码表
            app.alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            fbar=waitbar(0,'初始化密码表');
            pause(0.3)
            for i=1:26
                waitbar(i/26,fbar,'初始化中,请稍后');
                pause(0.01)
                for j=1:26
                    app.Mat(i,j)=' ';
                end
            end
            waitbar(1,fbar,'密码表初始化完成');
            pause(0.3)
            logRefresh_func_De(app,'密码表初始化完成')
            %填充26*26的密码表
            waitbar(0,fbar,'密码表填充');
            pause(0.3)
            cat='';
            for i=1:26
                waitbar(i/26,fbar,'密码表填充中,请稍后');
                pause(0.01)
                if i==1
                    app.Mat(i,:)=app.alphabet;
                else
                    app.Mat(i,:)=strcat(app.alphabet(i:end),cat);
                end
                cat=strcat(cat,app.alphabet(i));
            end
            waitbar(1,fbar,'密码表填充完成');
            pause(0.3)
            logRefresh_func_De(app,'密码表填充完成')
            
            %获取密钥以及密文
            Key_text_De=upper(app.Key_De.Value);
            Ciphertext=upper(app.Crypt_De.Value);
            keytext_De=Ciphertext;
            
            
            %确定密文和密钥之间映射关系
            for i=1:length(Ciphertext)
                %判断该字符对应着密钥中的哪一个字符
                if mod(i,length(Key_text_De))==0
                    keytext_De(i)=Key_text_De(length(Key_text_De));
                else
                    keytext_De(i)=Key_text_De(mod(i,length(Key_text_De)));
                end
            end
            
            %开始解密
            pause(0.3)
            Plaintext='';
            for i=1:length(Ciphertext)
                waitbar(i/length(Ciphertext),fbar,'解密中,请稍后');
                pause(0.01)
                y=find(app.alphabet==keytext_De(i));
                x=find(app.Mat(y,:)==Ciphertext(i));
                Plaintext=strcat(Plaintext,app.alphabet(x));
            end
            waitbar(1,fbar,'解密完成');
            pause(0.3)
            close(fbar)
            logRefresh_func_De(app,'解密完成')
            app.Plaintext_De.Value=Plaintext;
end

3. 信息输出

介绍:加密界面信息输出函数logRefresh_func_En

function logRefresh_func_En(app,StrArrayNew)
            app.Ptime=datestr(now);
            app.LOG=strcat('[',app.Ptime(end-7:end),']');
            StrArrayNew=strcat(app.LOG,StrArrayNew);
            app.StrArray_En=[app.StrArray_En,StrArrayNew,newline];
            app.Process_En.Value=app.StrArray_En;
end

介绍:解密界面信息输出函数logRefresh_func_De

function logRefresh_func_De(app,StrArrayNew)
            app.Ptime=datestr(now);
            app.LOG=strcat('[',app.Ptime(end-7:end),']');
            StrArrayNew=strcat(app.LOG,StrArrayNew);
            app.StrArray_De=[app.StrArray_De,StrArrayNew,newline];
            app.Process_De.Value=app.StrArray_De;
end

4. 交互界面

Matlab2019b的mlapp开发环境

MATLAB实现维吉尼亚密码加解密_第1张图片

四、数据测试与分析

1. 数据测试

明文: wearediscoveredsaveyourself

密钥: deceptive

密文: ZICVTWQNGRZGVTWAVZHCQYGLMGJ

  1. 加密过程

MATLAB实现维吉尼亚密码加解密_第2张图片

MATLAB实现维吉尼亚密码加解密_第3张图片

  1. 解密过程

MATLAB实现维吉尼亚密码加解密_第4张图片

MATLAB实现维吉尼亚密码加解密_第5张图片

  1. 加解密演示

MATLAB实现维吉尼亚密码加解密_第6张图片

2. 分析

维吉尼亚密码是一种多表代换密码。加密与解密双方需要约定一个共同的密钥词,用于加密与解密。加密方需要将密钥的每一个字符与明文的每一个字符进行匹配,根据两者的位置,在维吉尼亚密码表中确定一个唯一的密文字符。对每一个明文字符与密文字符对进行同样的处理,最终将每一个密文字符拼接后便可以得到密文字符串。解密方在获取密文后,同样需要将密文字符与密钥字符进行一一匹配。首先根据每一对字符对中的密钥字符在字母表中的位置y,在维吉尼亚密码表中确定第y行。随后在第y行中寻找对应的密文字符所在的位置x。最终可以确定该位明文字符为字母表中第x为的字母。对每一对字符对进行同样的操作,最终将每一个明文字符拼接后便可以得到明文字符串。

五、总结

  1. 维吉尼亚密码也是一种代换密码,但是一种多表代换密码,加密强度更高。

  1. 在对维吉尼亚密码加解密实现的过程中,也涉及到了非常多的字符串处理,如在初始化维吉尼亚密码表时,需要用到for循环,将字母表的顺寻进行处理,并且拼接,最终得到维吉尼亚密码表

  1. 在实现加密与解密时,需要确定每一个明文字符或者密文字符所对应的密钥字符。这里,可以使用一个额外的字符数组来存储对应位置的密钥字符,也可以使用模运算的方式存储下来对应密钥字符在整个密钥中的位置或者字母表中的位置。实现索引的方式很多,只需要确保明文字符与密钥字符相对应,并且能正确确定密文字符即可

  1. 在实现对字符串的拼接操作时,大量地使用了strcat来进行字符之间的连接,进而实现加密与解密操作

5. 起初想要将维吉尼亚密码表作为属性存储,这样可以使得加密方与解密方无需额外地初始化密码表,消耗加解密时间。但是这样的公用方式在实际的加解密过程中不太可行,因此最终还是让加密方与解密方都需要进行维吉尼亚密码表的初始化

你可能感兴趣的:(密码学,Matlab,matlab,开发语言)