二、方案设计 1. 加密过程 首先获取明文字符串,并对明文字符串做预处理,将字符串中的所有空格删除,并将所有字母大写 此外,由于Hill密码要求每次计算时,明文字符的个数需要与密钥矩阵的行数相同,因此需要确保明文字符串的长度是行数的整数倍。所以,长度不足时,使用明文字符串的最后一个字符进行尾部填充 预处理结束后,获取密钥矩阵规模(必须是方阵)以及密钥矩阵元素 在获取到密钥矩阵元素后,需要对文本框内的元素进行矩阵化处理(注意Matlab文本框中需要按列输入矩阵元素),以空格为分隔符将每个元素从文本款中提取出来,并存储到密钥矩阵中,直至最后一个字符 密钥矩阵初始化结束后,可以开始加密。假设密钥矩阵规模为n*n,那么每次加密时,使用n个明文字符与密钥矩阵相乘,得到每次加密后的n个密文字符。以此类推,直至最后一组明文字符也运算完毕。最后将所有组别的密文字符拼接在一起,便得到最终加密后的密文字符串。 2. 解密过程 首先获取密文字符串,由于密文字符串中已无空格以及小写字符的存在,因此无需进行预处理 随后获取密钥矩阵规模(必须是方阵)以及密钥矩阵元素 在获取到密钥矩阵元素后,需要对文本框内的元素进行矩阵化处理(注意Matlab文本框中需要按列输入矩阵元素),以空格为分隔符将每个元素从文本款中提取出来,并存储到密钥矩阵中,直至最后一个字符 接下来需要对密钥矩阵的逆矩阵进行计算。首先计算密钥矩阵的行列式N,随后计算N关于26的逆元I。紧接着,需要确定密钥矩阵的伴随矩阵,计算方式为A=mod(inv(matrix)*det(matrix),26)。最后通过计算逆矩阵,计算方式为De_matrix=mod(NI*Accompanny,26) 计算得到密钥矩阵的逆矩阵后,可以开始解密。假设密钥矩阵的规模依旧为n*n,那么每次解密时,使用n个密文字符与逆矩阵相乘,得到每次解密后的n个明文字符。以此类推,直至最后一组密文字符也运算完毕。最后将所有组别的明文字符拼接在一起,便得到最终解密后的明文字符串。 3. 信息输出 设置两个信息输出函数,分别实现加密界面和解密界面的信息输出 4. 交互界面 基于Matlab2019b中的mlapp编程实现 |
三、方案实现 1. 加密过程 介绍:加密按钮EnButtom回调函数 function EnButtonPushed(app, event)
ifstrcmp(app.Plaintext_En.Value,'')
logRefresh_func_En(app,'请输入明文');
return
end
if(app.ROW_En.Value==0||app.COLUM_En.Value==0)
logRefresh_func_En(app,'请输入正确的矩阵规模');
return
end
ifstrcmp(app.NUM_En.Value,'')
logRefresh_func_En(app,'请输入完整矩阵信息');
return
end
logRefresh_func_En(app,'字符串预处理中');
fbar=waitbar(0,'字符串预处理中');
plaintext_en=upper(app.Plaintext_En.Value);
%删除明文中的空格
Bridge='';
for i=1:length(plaintext_en)
ifplaintext_en(i)==' '
continue
else
Bridge=strcat(Bridge,plaintext_en(i));
end
end
plaintext_en=Bridge;
% 获取矩阵的行数,相乘时需要确保字符数与行数相等,因此不足时需要对字符串尾部进行填充无关字符
row=app.ROW_En.Value;
colum=app.COLUM_En.Value;
times=row-mod(length(plaintext_en),row);
iftimes~=0&×~=row
tail=plaintext_en(length(plaintext_en));
for i=1:times
plaintext_en=strcat(plaintext_en,tail);
end
end
logRefresh_func_En(app,'字符串处理完毕');
waitbar(1,fbar,'字符串处理完毕')
pause(0.3)
%将获取到的数值转换为矩阵
matrix=reshape(str2double(regexp(app.NUM_En.Value,' ','split')),[row,colum]);
logRefresh_func_En(app,'开始加密');
waitbar(0,fbar,'开始加密')
pause(0.3)
%开始加密,每colum个字符进行一次加密
ciphertext='';
plain_mat=abs(plaintext_en)-65;
for i=1:length(plain_mat)
waitbar(i/length(plain_mat),fbar,'加密中');
pause(0.01)
if mod(i,row)==0
results=mod(plain_mat(i-row+1:i)*matrix,26);
for j=1:length(results)
ifresults(j)==0
ciphertext=strcat(ciphertext,'A');
else
ciphertext=strcat(ciphertext,app.alphabet(results(j)+1));
end
end
end
end
logRefresh_func_En(app,'加密完成');
waitbar(1,fbar,'加密完成')
pause(0.3)
close(fbar)
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
if(app.ROW_De.Value==0||app.COLUM_De.Value==0)
logRefresh_func_De(app,'请输入正确的矩阵规模');
return
end
ifstrcmp(app.NUM_De.Value,'')
logRefresh_func_De(app,'请输入完整矩阵信息');
return
end
row=app.ROW_De.Value;
colum=app.COLUM_De.Value;
matrix=reshape(str2double(regexp(app.NUM_De.Value,' ','split')),[row,colum]);
ciphertext=app.Crypt_De.Value;
logRefresh_func_De(app,'获取逆矩阵中,请稍后');
fbar=waitbar(0,'获取逆矩阵中,请稍后');
%确定解密密钥矩阵
%首先求解矩阵的行列式
for i=1:10000000000000
if(mod(det(matrix)*i,26)-1.0000<2.7978e-12)
NI=i;
waitbar(1,fbar,'逆矩阵获取成功')
pause(0.3);
logRefresh_func_De(app,'逆矩阵获取成功');
break;
end
end
%确定原矩阵的伴随矩阵
Accompanny=mod(inv(matrix)*det(matrix),26);
%确定解密矩阵
De_matrix=mod(NI*Accompanny,26);
logRefresh_func_De(app,'开始解密');
waitbar(0,fbar,'开始解密')
pause(0.3)
%获取密文,开始解密
plaintext='';
cipher_mat=abs(ciphertext)-65;
for i=1:length(cipher_mat)
waitbar(i/length(cipher_mat),fbar,'解密中,请稍后')
pause(0.01)
if mod(i,row)==0
results=mod(cipher_mat(i-row+1:i)*De_matrix,26);
for j=1:length(results)
ifresults(j)==0
plaintext=strcat(plaintext,'A');
else
plaintext=strcat(plaintext,app.alphabet(results(j)+1));
end
end
end
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开发环境
|