📄 desf.cpp
字号:
// DESF.cpp: implementation of the DESF class.
//
//////////////////////////////////////////////////////////////////////
#include "DESF.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// permuted choice table (PC1)
const static int pc1[56] = {
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
};
// permuted choice key (PC2)
const static int pc2[48] = {
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
};
// number left rotations of pc1
static int ls[16] = {
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
// initial permutation (IP)
const static int ip[64] = {
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
};
// expansion operation matrix (E)
const static int e[48] = {
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
};
// The (in)famous S-boxes
const static int sbox[8][64] = {
// S1
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
// S2
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
// S3
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
// S4
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
// S5
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
// S6
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
// S7
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
// S8
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
// 32-bit permutation function P used on the output of the S-boxes
const static int p[32] = {
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
};
// final permutation IP^-1
const static int fp[64] = {
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
};
DESF::DESF()
{
}
DESF::~DESF()
{
}
DESF::chartobits(chars ch, bits *bts) //字符串变换成二进制
{
int cnt1,cnt2,pos;
for(cnt1=0;cnt1<ch.totalchar;cnt1++)
{
pos=int(ch.ch[cnt1]);
pos=pos<0 ? pos+256 : pos; //负数取补码
pos=pos+28; //为什么+28
for(cnt2=7;cnt2>=0;cnt2--)
{
bts->bit[cnt1*ch.totalchar+cnt2]=(pos%2!=0) ? true:false;
pos/=2;
}
}
bts->totalbit=ch.totalchar*8;
}
DESF::bitstochar(bits bts, chars *ch) //二进制变换成字符串
{
int cnt1,cnt2,pos,power;
for(cnt1=0;cnt1<8;cnt1++)
{
pos=0;
power=128;
for(cnt2=0;cnt2<8;cnt2++)
{
if(bts.bit[cnt1*8+cnt2]) pos+=power; //数组最左边是最高位
power/=2;
}
ch->ch[cnt1]=char(pos-28);
}
ch->totalchar=bts.totalbit/8;
}
DESF::bitmaping(int bitmapno, bits inbts, bits *outbts) //所有需要查表的置换(无S盒)
//第二、三个参数为什么一个用普通变量,一个用变量的指针
{
int cnt,mapsize;
switch(bitmapno) //确定需要置换的长度
{
case 1: mapsize=64 ;break; //ip
case 2: mapsize=64 ;break; //fp
case 3: mapsize=48 ;break; //e
case 4: mapsize=32 ;break; //p
case 5: mapsize=56 ;break; //pc1
case 6: mapsize=48 ;break; //pc2
}
outbts->totalbit=mapsize; //需要置换的的数组的位数
for(cnt=0;cnt<mapsize;cnt++)
{
switch(bitmapno) //进行查表置换
{
case 1: outbts->bit[cnt]=inbts.bit[ip[cnt]-1] ; break;
case 2: outbts->bit[cnt]=inbts.bit[fp[cnt]-1] ; break;
case 3: outbts->bit[cnt]=inbts.bit[e[cnt]-1] ; break;
case 4: outbts->bit[cnt]=inbts.bit[p[cnt]-1] ; break;
case 5: outbts->bit[cnt]=inbts.bit[pc1[cnt]-1] ;break;
case 6: outbts->bit[cnt]=inbts.bit[pc2[cnt]-1] ;break;
}
}
}
DESF::InitIP(bits bts64, bits *Lbts32, bits *Rbts32) //IP置换
{
int cnt;
bits tempbts;
bitmaping(1,bts64,&tempbts); //IP置换
for(cnt=0;cnt<32;cnt++) //将置换后的二进制分成左右两半
{
Lbts32->bit[cnt]=tempbts.bit[cnt];
Rbts32->bit[cnt]=tempbts.bit[cnt+32];
}
Lbts32->totalbit=32;
Rbts32->totalbit=32;
}
DESF::FinalIP(bits Lbts32, bits Rbts32, bits *bts64)
{
int cnt;
bits tempbts;
for(cnt=0;cnt<32;cnt++)
{
tempbts.bit[cnt]=Lbts32.bit[cnt];
tempbts.bit[cnt+32]=Rbts32.bit[cnt];
}
tempbts.totalbit=64;
bitmaping(2,tempbts,bts64);
}
DESF::leftshift(bits *bit28, int times) //密钥移位
{
bool lastbit;
int cnt1,cnt2;
for(cnt1=0;cnt1<times;cnt1++)
{
lastbit=bit28->bit[0]; //把需要移位的数组的第一位放在lastbit
for(cnt2=0;cnt2<bit28->totalbit-1;cnt2++)
bit28->bit[cnt2]=bit28->bit[cnt2+1]; //原数组左移1位
bit28->bit[bit28->totalbit-1]=lastbit; //把左移出来的一位,也就是lastbit放如新数组的最后一位
}
}
DESF::pc1tran(bits bts64, bits *Cbts28, bits *Dbts28) //密钥pc1变换,并且把密钥分成左右两边
{
int cnt;
bits tempbts;
bitmaping(5,bts64,&tempbts); //pc1变换
for(cnt=0;cnt<28;cnt++)
{
Cbts28->bit[cnt]=tempbts.bit[cnt]; //分成左右两边
Dbts28->bit[cnt]=tempbts.bit[cnt+28];
}
Cbts28->totalbit=28;
Dbts28->totalbit=28;
}
DESF::pc2tran(bits Cbts28, bits Dbts28, bits *Kbts48)
{
int cnt;
bits tempbts;
for(cnt=0;cnt<28;cnt++) //将移位后的密钥左右合并
{
tempbts.bit[cnt]=Cbts28.bit[cnt];
tempbts.bit[cnt+28]=Dbts28.bit[cnt];
}
tempbts.totalbit=56;
bitmaping(6,tempbts,Kbts48); //pc2变换
}
DESF::keygen(bits key, bitarray *subkey) //生成16个子密钥
{
bits Cbts28,Dbts28,Kbts48;
int cnt;
pc1tran(key,&Cbts28,&Dbts28); //经过pc1变换后的密钥左右两边存放Cbts28、Dbts28
for(cnt=0;cnt<16;cnt++)
{
leftshift(&Cbts28,ls[cnt]); //密钥移位
leftshift(&Dbts28,ls[cnt]);
pc2tran(Cbts28,Dbts28,&Kbts48); //pc2
subkey->bitarr[cnt]=Kbts48; //bitarr[cnt]是结构体数组
}
}
DESF::etran(bits bts32, bits *bts48) //e扩展
{
bitmaping(3,bts32,bts48);
}
DESF::bitToSBoxPos(bits bts48, int boxno, int *row, int *col) //算出S盒行列
//为什么要先用“?”进行选择?这里也可以用pow函数
{
* row=(bts48.bit[boxno*6]? 2:0)+(bts48.bit[boxno*6+5]? 1:0);
* col=(bts48.bit[boxno*6+1]? 8:0)+(bts48.bit[boxno*6+2]? 4:0)+
(bts48.bit[boxno*6+3]? 2:0)+(bts48.bit[boxno*6+4]? 1:0);
}
DESF::sboxtran(bits bts48, bits *bts32) //S盒
{
int cnt1,cnt2,row,col,boxout;
for(cnt1=0;cnt1<8;cnt1++) //8个S盒
{
bitToSBoxPos(bts48,cnt1,&row,&col); //得出每个S盒子的行列
boxout=sbox[cnt1][row*16+col]; //把(行*16+列)相当于把原来S盒的二维数组转换成一维
for(cnt2=3;cnt2>=0;cnt2--) //把从S盒子输出的十进制数转换为二进制
{
bts32->bit[cnt1*4+cnt2]=(boxout%2!=0)? true:false;
boxout/=2;
}
}
bts32->totalbit=32;
}
DESF::ptran(bits bts32, bits *fout) //P置换
{
bitmaping(4,bts32,fout);
}
DESF::ftran(bits inbts32, bits keyi, bits *fRes)
{
bits bts48,bts32,xorRes48;
etran(inbts32,&bts48);
exclusiveOR(bts48,keyi,&xorRes48);
sboxtran(xorRes48,&bts32);
ptran(bts32,fRes);
}
DESF::exclusiveOR(bits bts1, bits bts2, bits *xorRes) //扩展后的右边与密钥相异或
{
int cnt;
xorRes->totalbit=bts1.totalbit;
for(cnt=0;cnt<bts1.totalbit;cnt++)
xorRes->bit[cnt]=bts1.bit[cnt]^bts2.bit[cnt];
}
DESF::desblock(chars intext8, chars key, bool encode, chars *outtext8) //DES加密(解密)模块
{
int cnt,keypos;
bits inbts,Lbts,Rbts,oldLbts;
bits keybit,outbts,fRes;
bitarray subkey;
chartobits(intext8,&inbts); //明文8个字节转换成二进制
chartobits(key,&keybit); //密钥8个字节转换成二进制
keygen(keybit,&subkey); //每轮的密钥
InitIP(inbts,&Lbts,&Rbts); //IP变换
for(cnt=0;cnt<16;cnt++) //进行16轮加密(解密)迭代
{
oldLbts=Lbts;
Lbts=Rbts;
keypos=encode ? cnt : (15-cnt); //选择密钥
ftran(Rbts,subkey.bitarr[keypos],&fRes); //f函数
exclusiveOR(oldLbts,fRes,&Rbts); //原来的左边和经过f函数的右边相异或
}
FinalIP(Rbts,Lbts,&outbts); //~IP,注意参数放的位置
bitstochar(outbts,outtext8);
}
DESF::desEncode(char mfile[], char key[], char cfile[]) //加密,调用函数desCoding
{
desCoding(mfile,key,cfile,true);
}
DESF::desDecode(char mfile[], char key[], char cfile[]) //解密,调用函数desCoding
{
desCoding(mfile,key,cfile,false);
}
DESF::desCoding(char mfile[], char key[], char cfile[], bool codedir) //将文件中字符串分成8字节一组进行加密(解密)
{
int cnt1,cnt2;
chars inch,inkey,outch;
FILE * mfp;
FILE * cfp;
for(cnt1=0;cnt1<8;cnt1++)
inkey.ch[cnt1]=key[cnt1];
inkey.totalchar=8;
if((mfp=fopen(mfile,"r"))==NULL) //判断读入文件“mfile”是不是空
{cout<<"Cannot open the message file"<<endl;}
else
{
cfp=fopen(cfile,"w"); //新建一个文件“cfile”
cnt1=0;
inch.ch[cnt1]=fgetc(mfp); //从mfp读入字符并存放数组ch[8]
inch.totalchar=8;
cnt2=0;
while(!feof(mfp)) //判断文件有没有结束
{
cnt1++;
cnt2++;
inch.ch[cnt1]=fgetc(mfp);
if(cnt1==7)
{
desblock(inch,inkey,codedir,&outch);
for(cnt1=0;cnt1<8;cnt1++) //把密文从outch中取出存放cfp
fputc(outch.ch[cnt1],cfp);
cnt1=-1; //cnt1设置成-1,然后再次循环到=7
}
}
cnt2=cnt2%8; //判断明文(密文)是否正好是8字节的倍数
if(cnt2!=0) //处理最后剩下不足八字节的那部分
{
for(cnt1=0;cnt1<(8-cnt2);cnt1++) //不足8字节的补空格
inch.ch[cnt1+cnt2]=' ';
inch.totalchar=8;
desblock(inch,inkey,codedir,&outch);
for(cnt1=0;cnt1<8;cnt1++)
fputc(outch.ch[cnt1],cfp);
}
fclose(mfp);
fclose(cfp);
}
}
DESF::dispfile(char fn[]) //显示读入的文件
{
FILE *fp;
char ch;
if((fp=fopen(fn,"r"))==NULL) //判断读入文件是不是空
{cout<<"Cannot open the file to display"<<endl;}
else
{
while(!feof(fp))
{
ch=fgetc(fp);
cout<<ch;
}
cout<<endl;
}
}
float DESF::bitdiff(char mfile[], char cfile[], float *bitdiff8byte)
{
FILE * mfp,* cfp;
int ttch=0,xorRes,ttbitdiff=0;
char mch,cch;
float bdiff=0;
if((mfp=fopen(mfile,"r"))==NULL)
{cout<<"Cannot open the file to compare"<<endl;}
if((cfp=fopen(cfile,"r"))==NULL)
{cout<<"Cannot open the file to compare"<<endl;}
else
{
while(!feof(mfp)&!feof(cfp))
{
ttch++;
mch=fgetc(mfp);
cch=fgetc(cfp);
xorRes=mch^cch;
ttbitdiff+=(xorRes&1)+(xorRes&2)/2+(xorRes&4)/4+(xorRes&8)/8+
(xorRes&16)/16+(xorRes&32)/32+(xorRes&64)/64+(xorRes&128)/128;
}
bdiff=float(ttbitdiff)*100/float(ttch*8);
}
*bitdiff8byte=float(ttbitdiff)*100/float(8*8);
return bdiff;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -