📄 crijndael.cpp
字号:
SubBytes();
ShiftRows();
AddRoundKey();
}
void CRijndael::Decryption()//解密
{
int j,k=0;
round=Nr;
AddRoundKey();
round=round-1;
for(j=Nr-1;j>0;j--)
{
InvShiftRows();
InvSubBytes();
AddRoundKey();
round=round-1;
InvMixColumns();
}
InvShiftRows();
InvSubBytes();
AddRoundKey();
}
bool CRijndael::EncrypFile()
{
long i,j,k,len,count,size;
int remain;
byte *temp,(*in_stream)[4][4];
State=NULL;
Cur_Round=0;
/////////////获取文件名//////////////
len=Source.GetLength();//取得文件长度(字节)
if(len%16==0)//计算总的加密轮数
Total_Round=len/16;
else
Total_Round=len/16+1;
remain=len;//计算不够用于加密的字节数
while(remain>=16)
{
if(remain>=MaxSize)
size=MaxSize;
else
size=remain-remain%16;
len=size/16;
in_stream=new byte[len][4][4];//设置读入缓冲区
count=remain/size;//计算读取文件的次数
while((in_stream==NULL)&&(size>16))//循环计算可得到的最大缓冲区
{
size=size/2;
if(size%16!=0)
size=size+(16-size%16);
if(size<16)//若可得的最大缓冲区小于16个字节时,为错误情形
{
ErrorMessage=ErrorMessage+"\n内存空间不足!";
Source.Close();
Target.Close();
return false;
}
len=size/16;
count=remain/size;//计算读取文件的次数
in_stream=new byte[len][4][4];//设置读入缓冲区
}
for(i=0;i<count;i++)
{
try
{
Source.Read(in_stream,size);//从明文文件中读入size个字节内容到缓冲区
}
catch(...)//读入文件失败
{
ErrorMessage=ErrorMessage+"\n读入文件失败!";
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
for(j=0;j<len;j++)
{
State=&(in_stream[j][0]);
Encryption();//调用加密函数
Cur_Round++;//当前轮数加1
}
try
{
Target.Write(in_stream,size);//将缓冲区的size个字节内容写入到密文文件中
}
catch(...)//写入文件失败
{
ErrorMessage=ErrorMessage+"\n写入文件失败!";
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
}
remain=remain-size*count;//计算未处理的文件大小
if(remain<16&&remain>0)
{
Target.Seek(-(16-remain),CFile::current);//当前指针后移(相对于当前位置)remain=2
temp=new byte[remain];
if(temp==NULL)
{
ErrorMessage=ErrorMessage+"\n读入文件失败!";
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
byte *p=NULL;
p=&(State[0][0]);
try
{
Source.Read(temp,remain);
}
catch(...)//读入文件失败
{
ErrorMessage=ErrorMessage+"\n读入文件失败!";
delete []temp;
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
k=0;
for(j=remain;j<16;j++,k++)
*(p+k)=*(p+j);//k=16-remain
for(j=0;j<remain;j++,k++)
*(p+k)=temp[j];
Encryption();//调用加密函数
Cur_Round++;//当前轮数加1
try
{
Target.Write(State,16);
}
catch(...)//写入文件失败
{
ErrorMessage=ErrorMessage+"\n写入文件失败!";
delete []temp;
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
delete []temp;
remain=0;
}
delete []in_stream;
}
Source.Close();
Target.Close();
for(i=0;i<4;i++)//释放密钥的内存并置空
{
delete key[i];
key[i]=NULL;
delete w[i];
w[i]=NULL;
}
return true;
}
bool CRijndael::DecrypFile()
{
long i,j,k=0,len,count,size;
int remain;
byte *temp=NULL,*s=NULL,(*in_stream)[4][4];
State=NULL;
Cur_Round=0;
/////////////获取文件名//////////////
len=Source.GetLength();//取得文件长度(字节)
if(len%16==0)//计算总的解密轮数
Total_Round=len/16;
else
Total_Round=len/16+1;
remain=len;
if(remain%16!=0)
{
k=16+remain%16;
remain=remain-k;
}
while(remain>=16)
{
if(remain>=MaxSize)
size=MaxSize;
else
size=remain;
len=size/16;
in_stream=new byte[len][4][4];//设置读入缓冲区
count=remain/size;//计算读取文件的次数
while((in_stream==NULL)&&(size>16))//循环计算可得到的最大缓冲区
{
size=size/2;
if(size%16!=0)
size=size+(16-size%16);
if(size<16)//若可得的最大缓冲区小于16个字节时,为错误情形
{
ErrorMessage=ErrorMessage+"\n内存空间不足!";
Source.Close();
Target.Close();
return false;
}
len=size/16;
count=remain/size;//计算读取文件的次数
in_stream=new byte[len][4][4];//设置读入缓冲区
}
for(i=0;i<count;i++)
{
try
{
Source.Read(in_stream,size);//从明文文件中读入size个字节内容到缓冲区
}
catch(...)//读入文件失败
{
ErrorMessage=ErrorMessage+"\n读入文件失败!";
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
for(j=0;j<len;j++)
{
State=&(in_stream[j][0]);
Decryption();//调用解密函数
Cur_Round++;//当前轮数加1
}
try
{
Target.Write(in_stream,size);//将缓冲区的size个字节内容写入到密文文件中
}
catch(...)//写入文件失败
{
ErrorMessage=ErrorMessage+"\n写入文件失败!";
delete []in_stream;
Source.Close();
Target.Close();
return false;
}
}
remain=remain-size*count;//计算未处理的文件大小
delete []in_stream;
}
if(k!=0)
{
remain=k-16;
s=new byte[remain];//取出remain个字节
if(s==NULL)//分配内存失败
{
ErrorMessage=ErrorMessage+"\n内存空间不足!";
Source.Close();
Target.Close();
return false;
}
temp=new byte[remain];//取出remain个字节
if(temp==NULL)//分配内存失败
{
ErrorMessage=ErrorMessage+"\n内存空间不足!";
Source.Close();
Target.Close();
return false;
}
byte in[4][4];
try
{
Source.Read(s,remain);//跳过remain个字节
Source.Read(in,16);//做最后一轮解密
}
catch(...)//读入文件失败
{
ErrorMessage=ErrorMessage+"\n读入文件失败!";
Source.Close();
Target.Close();
delete []s;
delete []temp;
return false;
}
State=in;
Decryption();//调用解密函数
Cur_Round++;//当前轮数加1
byte *p=NULL;
p=&(State[0][0]);
for(i=0,j=16-remain;j<16;j++)
temp[i++]=*(p+j);
for(i=15-remain,j=15;i>=0;i--,j--)
*(p+j)=*(p+i);
for(j=0;j<remain;j++)
*(p+j)=s[j];
Decryption();//调用解密函数
Cur_Round++;//当前轮数加1
try
{
Target.Write(State,16);
Target.Write(temp,remain);
}
catch(...)//写入文件失败
{
ErrorMessage=ErrorMessage+"\n写入文件失败!";
delete []s;
delete []temp;
Source.Close();
Target.Close();
return false;
}
delete []s;
delete []temp;
}
Source.Close();
Target.Close();
for(i=0;i<4;i++)//释放密钥的内存并置空
{
delete key[i];
key[i]=NULL;
delete w[i];
w[i]=NULL;
}
return true;
}
CString CRijndael::EncrypStr()
{
long i,j,k,len,count;
int x;
byte in[4][4],*p=NULL;
p=&(in[0][0]);
len=source.GetLength();//取得字符串长度(字节)
count=len/16;//计算可直接加密的轮数
x=len%16;//计算不够用于加密的字节数
if(x==0)//刚好可以直接加密
for(i=0;i<count;i++)
{
for(j=0;j<16;j++)//获得明文
*(p+j)=source.GetAt(16*i+j);
State=in;
Encryption();//调用加密函数
for(j=0;j<16;j++)//获得密文
source.SetAt(16*i+j,*(p+j));
}
else//字符串末尾有不够16个字节的
{
for(i=0;i<count;i++)
{
for(j=0;j<16;j++)//获得明文
*(p+j)=source.GetAt(16*i+j);
State=in;
Encryption();//调用加密函数
for(j=0;j<16;j++)//获得密文
source.SetAt(16*i+j,*(p+j));
}
byte *temp=new byte[x];
j=16*count;
for(len=0;len<x;len++)//获得明文
temp[len]=source.GetAt(j+len);
for(k=0,j=x;j<16;j++,k++)
*(p+k)=*(p+j);//k=16-x
for(j=0;j<x;j++,k++)
*(p+k)=temp[j];
State=in;
Encryption();//调用加密函数
k=16*count-(16-x);
for(i=0;i<16;i++)
source.SetAt(k++,*(p+i));
delete []temp;
}
save=source;
return *target=source;
}
CString CRijndael::DecrypStr()
{
long i,j,len,count;
int x;
byte in[4][4],*p=NULL;
p=&(in[0][0]);
if(!save.IsEmpty())
source=save;
len=source.GetLength();//取得字符串长度(字节)
count=len/16;//计算可直接解密的轮数
x=len%16;//计算不够用于解密的字节数
if(x==0)//刚好可以直接解密
for(i=0;i<count;i++)
{
for(j=0;j<16;j++)//获得明文
//*(p+j)=Plaintext[16*i+j];
*(p+j)=source.GetAt(16*i+j);
State=in;
Decryption();//调用解密函数
for(j=0;j<16;j++)//获得密文
// Ciphertext[16*i+j]=*(p+j);
source.SetAt(16*i+j,*(p+j));
}
else//字符串末尾有不够16个字节的
{
for(i=0;i<count-1;i++)
{
for(j=0;j<16;j++)//获得明文
*(p+j)=source.GetAt(16*i+j);
State=in;
Decryption();//调用解密函数
for(j=0;j<16;j++)//获得密文
source.SetAt(16*i+j,*(p+j));
}
byte *s=new byte[x];//取出x个字节
byte *t=new byte[x];//取出x个字节
memset(s,0,x);
memset(t,0,x);
for(len=0;len<x;len++)//获得明文,先跳过x个字符
s[len]=source.GetAt(16*i+len);
for(len=0;len<16;len++)//获得明文
*(p+len)=source.GetAt(16*i+x+len);
State=in;
Decryption();//调用解密函数
for(j=16-x,i=0;j<16;j++)
t[i++]=*(p+j);
for(i=15-x,j=15;i>=0;i--,j--)
*(p+j)=*(p+i);
for(j=0;j<x;j++)
*(p+j)=s[j];
State=in;
Decryption();//调用解密函数
for(len=0;len<16;len++)
source.SetAt(16*(count-1)+len,*(p+len));//取得密文
for(len=0;len<x;len++)
source.SetAt(16*count+len,t[len]);//取得密文
delete []s;
delete []t;
}
return *target=source;
}
int CRijndael::GetCurPos()
{
return Cur_Round*100/Total_Round;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -