📄 des.cpp.txt
字号:
if (doEncrypt)
{// k = j % 6;
pstroutput+=sprintf(pstroutput,"%02d,", pc2[j]);
if ((j+1)%6==0 && doEncrypt) pstroutput+=sprintf(pstroutput,"|");
if ((j+1)%24==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
}
}
// if (doEncrypt) pstroutput+=sprintf(pstroutput,"\n");
for (j=0; j<48; j++)//
{
/* Select bits individually, check bit that goes to kn[j] */
//默认是所有密钥位都为零,只是要将为1的位重置一下即可。
if (pcr[pc2[j] - 1])//pc2是新的56位重新编号从1到56,pcr数组下标j从0起的,所以-1
{
/* mask it in if it's there */
k = j % 6;//j/6是j/6下取整。每6位写一个字节,共8字节,每字节还有两位没用。
kn[i][j / 6] |= byteBit[k] >> 2;// 0200, 0100, 040, 020, 010, 04, 02, 01 //128,64,32,16,8,4,2,1
} /* end of if *///先右移2位,即左边2位是空着的,k如何也取不到6(32,16,8,4,2,1,0,0)再或操作取位
if ( j==0 && doEncrypt)pstroutput+=sprintf(pstroutput,"步骤1-2-%d-3:第%d轮循环左移累计%d位,压缩置换后得到子钥K%d:\n",i,i,totRot[i],i);
if (doEncrypt)
{ k = j % 6;
pstroutput+=sprintf(pstroutput,"%d", kn[i][j / 6] & (byteBit[k] >> 2) ? 1:0);
if ((j+1)%6==0 && doEncrypt) pstroutput+=sprintf(pstroutput," ");
}
} /* end of j */
if( doEncrypt)pstroutput+=sprintf(pstroutput,"\n");
if(i==15&&doEncrypt) pstroutput+=sprintf(pstroutput,"/******************步骤1结束**************************/\n");
} /* end of for i */
return;
} /* SetKey() */
void TwxSetKey(unsigned char *key)
{
char pc1m[56]; /* Place to modify pc1 into */
char pcr[56]; /* Place to rotate pc1 into */
register int i ,j , k;
int m;
// kn[16][8] 用来存48*16bits密钥。
/* Clear key schedule */
for (i = 0; i < 16; i++)
{
for (j = 0; j < 8; j++)
kn[i][j] = 0;//密钥清零
} /* end of for i */
/* Convert pc1 to bits of key */
//取出56位重排到pc1m[j]
for (j = 0; j < 56; j++)
{
//pc1[0]=57,k=56,m=0x00,56>>3=0x7在第7字节,第0位,
//每个字节的起始编号位不再是校验位而是其右1位,56个位都左移1位即-1
//校验位:0,8,16,8k位
k = pc1[j]; /* Integer bit location 每字节都去了1校验位,*/
m = k & 07; /* find bit 归到一个字节里的哪一位(000-111 */
//k >> 3找到所第几位所属字节,再求于字节中第几位
pc1m[j] = (key[k >> 3] & byteBit[m]) ? 1 : 0;//k >> 3找到所第几位所属字节,再求于字节中第几位
} /* end of for j */
//16次循环移位,
for (i = 0; i < 16; i++)
{
/* rotate pc1 the right amount */
for (j = 0; j < 56; j++)
{
//实现循环左移:非常巧妙,即用右边(编号大)的位去写左边的(编号小)的位
k = j + totRot[i];/*static const char totRot[] = 1, 2(1+1), 4(1+1+2+2,教材上前面左移几项位数之和), 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};*/
//对于第0次,k=1...56 pc1m左边有剩,右边空虚。减28处理之
//对于j j=0...55 pcr
pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];//(j < 28 ? 28 : 56):取28则左半,取56右半,k - 28表示循环移位的
} /* end of for j */
/* Rotate left and right halves independently */
for (j=0; j<48; j++)//
{
/* Select bits individually, check bit that goes to kn[j] */
//默认是所有密钥位都为零,只是要将为1的位重置一下即可。
//二次选排
if (pcr[pc2[j] - 1])//pc2是新的56位重新编号从1到56,pcr数组下标j从0起的,所以-1
{//非零该位翻转。
/* mask it in if it's there */
k = j % 6;//确定字节中左边写第几位翻转,j/6是j/6下取整。每6位写一个字节,共8字节,每字节还有两位没用。
kn[i][j / 6] |= byteBit[k] >> 2;// j / 6定哪个字节翻转,0200, 0100, 040, 020, 010, 04, 02, 01 //128,64,32,16,8,4,2,1
} /* end of if */
//为何先右移2位再或赋值?,byteBit[k]赋值是将字节的第几位(从左第0始)赋值1,其它位为0;
//因kn[i][j]的左边2位是必是空着的,byteBit[k]不是的;
//如果k=5,则 byteBit[k]=0000 0100 k如何也取不到6(32,16,8,4,2,1,0,0)再或操作取位
} /* end of j */
} /* end of for i */
return;
}
void TwxConvertKnToHex(unsigned char *HexKey)
{
int i(0);
HexKey[0] |=kn[i][0 ]<<2;//kn[0]取6位
HexKey[0] |=kn[i][1]>>4;//kn[1]取2位
HexKey[1] |=kn[i][1]<<4;//kn[1]取4位
HexKey[1] |=kn[i][2]>>2;//kn[2]取4位
HexKey[2] |=kn[i][2]<<6;//kn[2]取2位
HexKey[2] |=kn[i][3];//kn[3]取6位
HexKey[3] |=kn[i][4 ]<<2;//kn[4]取6位
HexKey[3] |=kn[i][5]>>4;//kn[5]取2位
HexKey[4] |=kn[i][5]<<4;//kn[5]取4位
HexKey[4] |=kn[i][6]>>2;//kn[6]取4位
HexKey[5] |=kn[i][6]<<6;//kn[6]取2位
HexKey[5] |=kn[i][7];//kn[7]取6位
}
int main(int argc, char* argv[])
{
char command;
printf("\n");
cout <<"(谭文学制作.2006年3月20日.)DES算法之子密钥生成过程演示实验示范程序。\n输入s:生成密钥输出Kn[0]到屏幕!\n";
cout <<"输入f:生成密钥输出全过程到工程目录下文件:Des全过程.txt!\n";
cout <<"输入h:获得命令帮助!\n";
cout <<"输入e:退出程序!\n";
cout <<"请输入指令:";
loop:
cin >> command;
switch (command)
{
case 's':
{
unsigned char HexKey[6]={0};
char Key64bits[9]={0};
cout <<"\ninput Key64bits: ";
cin >> Key64bits;
printf("你的输入,请确认!如果不足8字符用NULL填充!\n");
for(int i=0;i<8;i++)
printf("%c,",Key64bits[i]);
printf("\n第0个48位子钥为:\n");
SetKey(1,(unsigned char *)Key64bits);
TwxConvertKnToHex((unsigned char *)HexKey);
for( i=0;i<6;i++)
printf("%02X",HexKey[i]);
printf("\n");
cout <<"输入s:生成密钥输出Kn[0]到屏幕!\n";
cout <<"输入f:生成密钥输出全过程到工程目录下文件:Des全过程.txt!\n";
cout <<"输入h:获得命令帮助!\n";
cout <<"输入e:退出程序!\n";
cout <<"请输入指令:";
goto loop;
}
case 'f':
{
char Key64bits[9]={0};
cout <<"\ninput Key64bits: ";
cin >> Key64bits;
pstroutput+=sprintf(pstroutput,"你的输入,请确认!不足8字符用NULL填充!\n");
for(int i=0;i<8;i++)
pstroutput+=sprintf(pstroutput,"%c,",Key64bits[i]);
pstroutput+=sprintf(pstroutput,"\nc");
fstream filetemp;
SetKey(1,(unsigned char*)Key64bits);
char strtempfile[256]={0};
GetCurrentDirectory(256,strtempfile);
char strfilename[256]="\\Des全过程.txt";
strcat(strtempfile,strfilename);
filetemp.open(strtempfile,ios::out,filebuf::openprot);
filetemp.write((unsigned char const *)pstroutput0,pstroutput-pstroutput0);
filetemp.close();
free(pstroutput0);
cout <<"输入s:生成密钥输出Kn[0]到屏幕!\n";
cout <<"输入f:生成密钥输出全过程到工程目录下文件:Des全过程.txt!\n";
cout <<"输入h:获得命令帮助!\n";
cout <<"输入e:退出程序!\n";
cout <<"请输入指令:";
goto loop;
}
case 'e':
{
return;
}
case 'h': ;
{
cout <<"输入s:生成密钥输出Kn[0]到屏幕!\n";
cout <<"输入f:生成密钥输出全过程到工程目录下文件!\n";
cout <<"输入h:获得命令帮助!\n";
cout <<"输入e:退出程序!\n";
cout <<"请输入指令:";
goto loop;
}
default:goto loop;
}
// printf("%s",pstroutput0);//输出到屏幕
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -