这篇博客是我的第一篇博客,写得不太好,请多多原谅。
我写这篇博客的目的主要是因为在网上很少有关于RC4算法的MATLAB实现,用java、c语言等实现的很多。因此我就想用MATLAB来实现一下,以弥补这空白。
RC4算法我在这里就不介绍,有兴趣的点RC4算法,这个链接去了解它的原理吧,链接的那篇博客说的挺好的。
这里RC4算法,我写了5个m文件函数,分别如下:
function ciphertext=RC4Code(plaintext,key,flag)
%RC4加密解密算法,输出密文
%plaintext 明文字符串
%key 密钥字符串
%flag 决定加密还是解密,0为解密,其他为加密
%made by Canlong Zhang
%初始化密文
ciphertext=[];
%s盒
s=[];
%获取明文长度
plaintextLength=length(plaintext);
%生成的密钥流
keySchedual=[];
%密钥调度算法
s=ksa(s,key);
%RPGA-伪随机生成算法
keySchedual=prga(s,keySchedual,plaintextLength);
%将密钥流每个字节转化为ASCII数值
keySchedualtASCII=double(keySchedual);
%如果flag不等于0,则加密,等于0,则解密
if flag~=0
%加密
ciphertext=rc4_encode(plaintext,keySchedualtASCII);
else if flag==0
ciphertext=plaintext;
%解密
rc4_decode(ciphertext,keySchedualtASCII);
end
end
function plaintext2=rc4_decode(ciphertext,keySchedualtASCII)
%解密
%ciphertext 密文
%keySchedualtASCII 密钥流的ASCII码
%made by Canlong Zhang
%获取密文长度
ciphertextLength=length(ciphertext);
%将明文每个字节转化为ASCII数值
ciphertextASCII=double(ciphertext);
plaintext2=[];
%为密文的每个字节用密钥流加密
for i=1:ciphertextLength
%将密钥流与明文字节进行异或处理,因为matlab无法直接对字节进行异或,因此在这里对数值进行异或处理
%bitxor只能对十进制数字进行异或处理
plaintextXORASCII=bitxor(ciphertextASCII(i),keySchedualtASCII(i));
plaintext2=[plaintext2 char(plaintextXORASCII)];
end
%输出明文
disp(['The ciphertext is:',ciphertext])
disp(['The decode plaintext is:',plaintext2])
function ciphertext=rc4_encode(plaintext,keySchedualtASCII)
%加密
%plaintext 明文
%keySchedualASCII 密钥流的ASCII码
%made by Canlong Zhang
%初始获密文
ciphertext=[];
%获取明文长度
plaintextLength=length(plaintext);
%将明文每个字节转化为ASCII数值
plaintextASCII=double(plaintext);
ciphertextASCII=1;
%为明文的每个字节用密钥流加密
for i=1:plaintextLength
%将密钥流与明文字节进行异或处理,因为matlab无法直接对字节进行异或,因此在这里对数值进行异或处理
%bitxor只能对十进制数字进行异或处理
ciphertextXORASCII=bitxor(plaintextASCII(i),keySchedualtASCII(i));
ciphertext=[ciphertext char(ciphertextXORASCII)];
end
%输出密文
disp(['The plaintext is:',plaintext])
disp(['The encode ciphertext is:',ciphertext])
function s=ksa(s,key)
%ksa-密钥调度算法-利用key来对s盒做一下置换,也就是对s和重新排序
%s 输入的s盒
%key 密钥字符串
%made by Canlong Zhang
%初始化s盒
for i=1:256
s(i)=i-1;
end
j=1;
%将密钥字符串转化为ascii码数组
keyASCII=double(key);
%获取密钥的长度+1
keyLength=length(key)+1;
for i=1:256
%i对密钥长度+1取余数
modIToKeyLength=mod(i,keyLength);
if modIToKeyLength==0
modIToKeyLength=length(key);
end
j=(j+s(i)+key(modIToKeyLength));
j=mod(j,256);
if j==0
j=256;
end
%将s盒中的角标为i和j交换
temp=s(j);
s(j)=s(i);
s(i)=temp;
end
s;
function keySchedual=prga(s,keySchedual,plaintextLength)
%PRGA(Pseudo Random-Generation Algorithm)伪随机生成算法,用来输入随机序列并修改s的党旗排列顺序
%s s盒
%keySchedual 密钥流
%plaintextLength 明文长度
%made by Canlong Zhang
i=1;
j=1;
for k=1:plaintextLength
i=mod(i+1,256);
j=mod(j+s(i),256);
%置换s(i)和s(j)
temp=s(j);
s(j)=s(i);
s(i)=temp;
%生成密钥流数组
keySchedualIndex=mod(s(i)+s(j),256);
%因为matlab的数组的索引是从1开始,因此,在index=0时,把它赋值为256
if keySchedualIndex==0
keySchedualIndex=256;
end
keySchedual=[keySchedual char(s(keySchedualIndex))];
end
keySchedual;
rc4第三个参数为决定是加密还是解密,如果为0,则是解密,否则是加密。
在运行程序之前要在MATLAB软件中输入:
slCharacterEncoding('UTF-8');
来设置编码为UTF-8,因为MATLAB默认的编码为ANSI,不然会出现加密或解密乱码,从而得不到正确的明文或密文,也不能用来加密或解密中文字符了。
注意: 设定编码为UTF-8,这个很重要我曾经由于没有写设置这个编码格式,所以总是加密出来的密文显示问号,而且加密不了中文,这个问题困惑了几乎一个学期,后来偶然看到有些人的程序是有这个设置,因此我也设置了这个,最终我的程序才能运行,而且才能加密中文。
运行程序的时候要放在英文目录下运行。
不知道为什么什么在程序运行加密解密后,再设置编码输出的中文才不会乱。但是如果在运行加密解密之前设置了编码再运行程序,这是后输出中文就会乱,因此为了不乱码,我把输出的全部换成英文。
不知道为什么在输出有中文的时候,第一次运行matlab,先运行后,编码,输出中文就没有问题:
但是,先关闭MATLAB后,第二次运行MATLAB,先编码后运行,输出中文就有问题: