📄 idea.cpp
字号:
// Idea.cpp: implementation of the CIdea class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MailEncrypt.h"
#include "Idea.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//以下实现组成二和组成三
/////////////////////////////////////////////////////////////
///////////////////////////
////组成二////
//加密和解密用到的私有方法
///////////////////////////
//加密方法用到的私有方法的实现
//[1].
//作用:生成加密子的密钥
void CIdea::en_key_idea(bit8 *userkey, bit16 *Z)
{
int i,j;
for (j=0; j<8; j++)
{
Z[j] = (userkey[0]<<8) + userkey[1];
userkey+=2;
}
for (i=0; j<KEYLEN; j++)
{
i++;
Z[i+7] = Z[i & 7] << 9 | Z[i+1 & 7] >> 7;
Z += i & 8;
i &= 7;
}
}
//[2].
//乘法求逆
bit16 CIdea::inv(bit16 x)
{
bit16 t0, t1;
bit16 q, y;
if (x <= 1)
return x;
t1 = 0x10001L / x;
y = 0x10001L % x;
if (y == 1)
return low16(1-t1);
t0 = 1;
do
{
q = x / y;
x = x % y;
t0 += q * t1;
if (x == 1)
return t0;
q = y / x;
y = y % x;
t1 += q * t0;
} while (y != 1);
return low16(1-t1);
}
//[3].
//作用:生成解密的子密钥
// 调用了[2].
void CIdea:: de_key_idea(bit16* Z, bit16* DK)
{
int j;
bit16 t1, t2, t3;
bit16 temp[KEYLEN];
bit16 *p = temp+ KEYLEN;
t1 = inv(*Z++);
t2 = -*Z++;
t3 = -*Z++;
*--p = inv(*Z++);
*--p = t3;
*--p = t2;
*--p = t1;
for (j = 1; j < ROUNDS; j++)
{
t1 = *Z++;
*--p = *Z++;
*--p = t1;
t1 = inv(*Z++);
t2 = -*Z++;
t3 = -*Z++;
*--p = inv(*Z++);
*--p = t2;
*--p = t3;
*--p = t1;
}
t1 = *Z++;
*--p = *Z++;
*--p = t1;
t1 = inv(*Z++);
t2 = -*Z++;
t3 = -*Z++;
*--p = inv(*Z++);
*--p = t3;
*--p = t2;
*--p = t1;
for (j=0; j<KEYLEN; j++)
{
DK[j]=temp[j];
}
}
//[4].
//乘法
bit16 CIdea::mul(bit16 a,bit16 b)
{
bit32 p;
if (a)
{
if (b)
{
p = (bit32)a * b;
b = low16(p);
a = p>>16;
return b - a + (b < a);
}
else
{
return 1-a;
}
}
else
{
return 1-b;
}
}
//[5].
//作用:加密,解密64Bit
// 调用了[4].
void CIdea::cipher_idea(bit8* bu1, bit8* bu2,bit16* Z)
{
bit16 x1, x2, x3, x4, s2, s3;
int r = ROUNDS;
bit16 *in, *out;
in=(bit16 *)bu1;
x1 = *in++;
x2 = *in++;
x3 = *in++;
x4 = *in;
do
{
MUL(x1,*Z++);
x2 += *Z++;
x3 += *Z++;
MUL(x4, *Z++);
s3 = x3;
x3 ^= x1;
MUL(x3, *Z++);
s2 = x2;
x2 ^= x4;
x2 += x3;
MUL(x2, *Z++);
x3 += x2;
x1 ^= x2;
x4 ^= x3;
x2 ^= s3;
x3 ^= s2;
} while (--r);
MUL(x1, *Z++);
out=(bit16 *)bu2;
*out++ = x1;
*out++ = x3 + *Z++;
*out++ = x2 + *Z++;
MUL(x4, *Z);
*out = x4;
}
//[6].
//利用随机种子生成对称密钥
// 同时修改随机种子的函数
void CIdea::MakeRadomKey(unsigned char*)
{
//先得到字符串型的随机种子
//化字符串型的随机种子成8字节字符串
//unsigned char RadomKeyString[8];
//( 必要时可利用DES中的sbox()函数 )
//利用IDEA类的加密字符串函数加密此字符串
//生成对称密钥(8字节)
//注:此时的密钥为随机种子成8字节字符串的两次
// (或经适当的变化)
//赋给charkey1
//CIdea idea;
//idea.SetKey();
//idea.EnString(RadomKeyString,charkey1);
//再来一次得到charkey2
//合并charkey1和charkey2成charkey
//利用IDEA类的解密字符串函数
//修改随机种子化成的8字节字符串
//unsigned char temp[8];
//idea.DeString(RadomKeyString,temp);
//化8字节字符串的随机种子成
//原来的字符串型的随机种子
//即从temp到RadomkeyString
}
//////////////
////组成三////
//////////////
//加密方法的实现
int CIdea::IdeaEncrypt(char *infilename,
char *outfilename)
{
//在测示版中
//密钥为用户输入
//而在正示版中
//要利用随机种子生成对称密钥
//MakeRadomKey(UserKey);
//生成加密子密钥
en_key_idea(UserKey, EnSubKeys);
//进行加密,包括3步
//第1步:打开文件
FILE *fin;
FILE *fout;
if( (fin=fopen(infilename,"rb")) == NULL)
{
MessageBox(NULL,
"不能打开源文件",
"出错",
MB_ICONSTOP|MB_OKCANCEL);
return CAN_NOT_OPEN_SOURCE_FILE;
}
if( (fout=fopen(outfilename,"wb")) == NULL )
{
MessageBox(NULL,
"不能打开目标文件",
"出错",
MB_ICONSTOP|MB_OKCANCEL);
return CAN_NOT_OPEN_DIRECT_FILE;
}
//第2步
//进行循环加密
//从文件中得到未加密的8个字符放于字符数组pBuffer内
//如果得到8个字符
//则可以直接IDEA加密
//如果因文件结束而得到的不够8个字符
//则用空字符凑成8个字符后再IDEA加密
//IDEA加密之后的字符数组存储在pBuffer内
//然后把pBuffer存储到加密后的文件中
//我们把加密后的文件存储成文本文件
int i;
unsigned char bu1[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
unsigned char bu2[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
while( ( !feof(fin) ) )
{
i=-1;
while( (i<7 ) && ( !feof(fin)) )
{
i++;
fread(&bu1[i],sizeof(unsigned char),1,fin);
}
//i=0时表示为8位
if (i==0)
break;
if(feof(fin))
{
for(int j=i;j<8;j++)
{
bu1[j]=(unsigned char) ('\0');
}
//用到了[4].
cipher_idea( bu1, bu2,EnSubKeys);
//以下把加密后的字符数组存储到加密后的文件中
for (i=0;i<8;i++)
{
fwrite(&bu2[i],sizeof(unsigned char),1,fout);
}
break;
}
cipher_idea( bu1, bu2,EnSubKeys);
//以下把加密后的字符数组存储到加密后的文件中
for (i=0;i<8;i++)
{
fwrite(&bu2[i],sizeof(unsigned char),1,fout);
}
}
//第3步.
//关闭文件
fclose(fin);
fclose(fout);
return SUCCESS;
}
//解密方法的实现
int CIdea::IdeaDecrypt(char *infilename,
char *outfilename)
{
//生成解密子密钥
en_key_idea(UserKey, EnSubKeys);
de_key_idea(EnSubKeys, DeSubKeys);
//进行解密:包括3步
//第1步
//打开文件
FILE *fin;
FILE *fout;
if( (fin=fopen(infilename,"rb")) == NULL)
{
MessageBox(NULL,
"不能打开源文件",
"出错",
MB_ICONSTOP|MB_OKCANCEL);
return CAN_NOT_OPEN_SOURCE_FILE;
}
if( (fout=fopen(outfilename,"wb")) == NULL )
{
MessageBox(NULL,
"不能打开目标文件",
"出错",
MB_ICONSTOP|MB_OKCANCEL);
return CAN_NOT_OPEN_DIRECT_FILE;
}
//第2步
//进行循环解密
//以下的处理同加密时的处理
//但由于这时的文件的长度已经为8的倍数了
//因次不必进行加空字符的处理了
int i;
unsigned char bu1[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
unsigned char bu2[8]={'\0','\0','\0','\0','\0','\0','\0','\0'};
while(! feof (fin))
{
i=-1;
while( (i < 7 ) && (! feof (fin)) )
{
i++;
fread(&bu1[i],sizeof(unsigned char),1,fin);
}
//i=0时表示为8位
if(i==0)
break;
cipher_idea( bu1, bu2,DeSubKeys);
for(i=0;i<8;i++)
{
fwrite(&bu2[i],sizeof(unsigned char),1,fout);
}
}
//第3步
//关闭文件
fclose(fin);
fclose(fout);
return SUCCESS;
}
//加密字符串的方法
void CIdea::EnString(unsigned char* before,unsigned char* after)
{
int i;
//首先要产生随机密钥
MakeRadomKey(UserKey);
en_key_idea(UserKey,EnSubKeys);
//先得到字符串的长度length
int length=strlen((const char*)before);
//复制一个before
unsigned char *tempbefore=new unsigned char[length];
unsigned char *tempafter=new unsigned char[length];
//用空字符补成的8倍数的长度
for(i=0; i<length+8-length%8; i++)
{
tempbefore[i]='\0';
tempafter[i]='\0';
}
for(i=0; i<length; i++)
{
tempbefore[i]=before[i];
}
//进行加密
unsigned char buf1[8];
unsigned char buf2[8];
for(i=0; i<length/8 + 1; i++)
{
int j;
for (j=0; j<8; j++)
{
buf1[j]=tempbefore[8*i+j];
}
cipher_idea(buf1,buf2,EnSubKeys);
for (j=0; j<8; j++)
{
tempafter[8*i+j]=buf2[j];
}
}
//返回加密结果
for (i=0; i<length; i++)
{
after[i]=tempafter[i];
}
}
//解密字符串的方法
void CIdea::DeString(unsigned char* before,unsigned char* after)
{
int i;
//先得到字符串的长度length
int length=strlen((const char*)before);
//复制一个before
unsigned char *tempbefore;
unsigned char *tempafter;
//用空字符补成的8倍数的长度
for(i=0; i<length+8-length%8; i++)
{
tempbefore[i]='\0';
tempafter[i]='\0';
}
for(i=0; i<length; i++)
{
tempbefore[i]=before[i];
}
//进行解密
unsigned char buf1[8];
unsigned char buf2[8];
for(i=0; i<length/8 + 1; i++)
{
int j;
for (j=0; j<8; j++)
{
buf1[j]=tempbefore[8*i+j];
}
cipher_idea(buf1,buf2,DeSubKeys);
for (j=0; j<8; j++)
{
tempafter[8*i+j]=buf2[j];
}
}
for (i=0; i<length; i++)
{
after[i]=tempafter[i];
}
}
//设置密钥的方法
void CIdea::SetKey(unsigned char * charkey)
{
int bb;
for(bb=0; bb<16; bb++)
{
UserKey[bb]=charkey[bb];
}
}
//返回密钥的方法
void CIdea::GetKey(unsigned char * charkey)
{
int dd;
for(dd=0; dd<16; dd++)
{
charkey[dd]=UserKey[dd];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -