第一次写原创东西,有不好的地方请多多包涵。此次写的是关于des密钥生成的,话不多说,先把代码给出如下
#include
int main()
{
char zz[]={"0000000100100011010001010110011110001001101010111100110111101111"};
char ll[29],rr[29],ww[49];
char z[65];
int bb[16]={1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28};
char ss[17],jj;
int i,j,k,l;
while(scanf("%s",ss)!=EOF)
{l=0;
for( i=0;i<16;i++)
{
switch(ss[i])
{
case '0':j=0;break;
case '1':j=1;break;
case '2':j=2;break;
case '3':j=3;break;
case '4':j=4;break;
case '5':j=5;break;
case '6':j=6;break;
case '7':j=7;break;
case '8':j=8;break;
case '9':j=9;break;
case 'A':j=10;break;
case 'B':j=11;break;
case 'C':j=12;break;
case 'D':j=13;break;
case 'E':j=14;break;
default:j=15;break;
}
j=4*j;
for(k=1;k<=4;k++)
{
z[l++]=zz[j++];
}
}
ll[0]=z[56];ll[1]=z[48];ll[2]=z[40];ll[3]=z[32];ll[4]=z[24];ll[5]=z[16];ll[6]=z[8];
ll[7]=z[0];ll[8]=z[57];ll[9]=z[49];ll[10]=z[41];ll[11]=z[33];ll[12]=z[25];ll[13]=z[17];
ll[14]=z[9];ll[15]=z[1];ll[16]=z[58];ll[17]=z[50];ll[18]=z[42];ll[19]=z[34];ll[20]=z[26];
ll[21]=z[18];ll[22]=z[10];ll[23]=z[2];ll[24]=z[59];ll[25]=z[51];ll[26]=z[43];ll[27]=z[35];
rr[0]=z[62];rr[1]=z[54];rr[2]=z[46];rr[3]=z[38];rr[4]=z[30];rr[5]=z[22];rr[6]=z[14];
rr[7]=z[6];rr[8]=z[61];rr[9]=z[53];rr[10]=z[45];rr[11]=z[37];rr[12]=z[29];rr[13]=z[21];
rr[14]=z[13];rr[15]=z[5];rr[16]=z[60];rr[17]=z[52];rr[18]=z[44];rr[19]=z[36];rr[20]=z[28];
rr[21]=z[20];rr[22]=z[12];rr[23]=z[4];rr[24]=z[27];rr[25]=z[19];rr[26]=z[11];rr[27]=z[3];
ll[28]=rr[28]='\0';
//printf("%s %s\n",ll,rr);
for(i=0;i<16;i++)
{ww[0]=ll[(13+bb[i])%28];ww[1]=ll[(16+bb[i])%28];ww[2]=ll[(10+bb[i])%28];ww[3]=ll[(23+bb[i])%28];ww[4]=ll[bb[i]%28];ww[5]=ll[(4+bb[i])%28];
ww[6]=ll[(2+bb[i])%28];ww[7]=ll[(27+bb[i])%28];ww[8]=ll[(14+bb[i])%28];ww[9]=ll[(5+bb[i])%28];ww[10]=ll[(20+bb[i])%28];ww[11]=ll[(9+bb[i])%28];
ww[12]=ll[(22+bb[i])%28];ww[13]=ll[(18+bb[i])%28];ww[14]=ll[(11+bb[i])%28];ww[15]=ll[(3+bb[i])%28];ww[16]=ll[(25+bb[i])%28];ww[17]=ll[(7+bb[i])%28];
ww[18]=ll[(15+bb[i])%28];ww[19]=ll[(6+bb[i])%28];ww[20]=ll[(26+bb[i])%28];ww[21]=ll[(19+bb[i])%28];ww[22]=ll[(12+bb[i])%28];ww[23]=ll[(1+bb[i])%28];
ww[24]=rr[(12+bb[i])%28];ww[25]=rr[(23+bb[i])%28];ww[26]=rr[(2+bb[i])%28];ww[27]=rr[(8+bb[i])%28];ww[28]=rr[(18+bb[i])%28];ww[29]=rr[(26+bb[i])%28];
ww[30]=rr[(1+bb[i])%28];ww[31]=rr[(11+bb[i])%28];ww[32]=rr[(22+bb[i])%28];ww[33]=rr[(16+bb[i])%28];ww[34]=rr[(4+bb[i])%28];ww[35]=rr[(19+bb[i])%28];
ww[36]=rr[(15+bb[i])%28];ww[37]=rr[(20+bb[i])%28];ww[38]=rr[(10+bb[i])%28];ww[39]=rr[(bb[i]-1)%28];ww[40]=rr[(5+bb[i])%28];ww[41]=rr[(24+bb[i])%28];
ww[42]=rr[(17+bb[i])%28];ww[43]=rr[(13+bb[i])%28];ww[44]=rr[(21+bb[i])%28];ww[45]=rr[(7+bb[i])%28];ww[46]=rr[(0+bb[i])%28];ww[47]=rr[(3+bb[i])%28];
ww[48]='\0';
printf("%s\n",ww);}}
return 0;
}
对于下面代码是实现将输入的十六进制转二进制的处理方法:
zz数组的每四位对应一个十六进制数
char zz[]={"0000000100100011010001010110011110001001101010111100110111101111"};
接下来就是对输入的初始十六进制密钥转二进制
l=0;
for( i=0;i<16;i++)
{
switch(ss[i])
{
case '0':j=0;break;
case '1':j=1;break;
case '2':j=2;break;
case '3':j=3;break;
case '4':j=4;break;
case '5':j=5;break;
case '6':j=6;break;
case '7':j=7;break;
case '8':j=8;break;
case '9':j=9;break;
case 'A':j=10;break;
case 'B':j=11;break;
case 'C':j=12;break;
case 'D':j=13;break;
case 'E':j=14;break;
default:j=15;break;
}
j=4*j;//此处j是指一个十六进制数对应的四位二进制在zz中的起始位置
for(k=1;k<=4;k++)
{
z[l++]=zz[j++];//此处z字符数组就是存十六进制密钥转为二进制数的
}
}
然后对于ll字符数组存的就是置换选择1后的前28密钥,rr字符数组存的就是置换选择1后的后28密钥。
对于bb数组存的就是第0圈到第i圈总共循环左移的位数。
接下来就是置换选择2:
这里要说明的是,对于置换选择2表中的第i比特指的就是字符数组的i-1时的字符,对于置换选择2表中的大于等于29的数,由于其相当于rr中的字符,所有我们首先减去28,然后再减去1。对于i-1或i-28-1的字符如何确定,请看我推导:
假设i-1或i-28-1的字符是循环左移前j处的字符,而循环左移的位数为h,则可知(j+28-h)=i-1或i-29,则j=(i+h-1)%28或(i+h-29)%28,此处h指的就是bb数组的循环左移的位数。
for(i=0;i<16;i++)
{ww[0]=ll[(13+bb[i])%28];ww[1]=ll[(16+bb[i])%28];ww[2]=ll[(10+bb[i])%28];ww[3]=ll[(23+bb[i])%28];ww[4]=ll[bb[i]%28];ww[5]=ll[(4+bb[i])%28];
ww[6]=ll[(2+bb[i])%28];ww[7]=ll[(27+bb[i])%28];ww[8]=ll[(14+bb[i])%28];ww[9]=ll[(5+bb[i])%28];ww[10]=ll[(20+bb[i])%28];ww[11]=ll[(9+bb[i])%28];
ww[12]=ll[(22+bb[i])%28];ww[13]=ll[(18+bb[i])%28];ww[14]=ll[(11+bb[i])%28];ww[15]=ll[(3+bb[i])%28];ww[16]=ll[(25+bb[i])%28];ww[17]=ll[(7+bb[i])%28];
ww[18]=ll[(15+bb[i])%28];ww[19]=ll[(6+bb[i])%28];ww[20]=ll[(26+bb[i])%28];ww[21]=ll[(19+bb[i])%28];ww[22]=ll[(12+bb[i])%28];ww[23]=ll[(1+bb[i])%28];
ww[24]=rr[(12+bb[i])%28];ww[25]=rr[(23+bb[i])%28];ww[26]=rr[(2+bb[i])%28];ww[27]=rr[(8+bb[i])%28];ww[28]=rr[(18+bb[i])%28];ww[29]=rr[(26+bb[i])%28];
ww[30]=rr[(1+bb[i])%28];ww[31]=rr[(11+bb[i])%28];ww[32]=rr[(22+bb[i])%28];ww[33]=rr[(16+bb[i])%28];ww[34]=rr[(4+bb[i])%28];ww[35]=rr[(19+bb[i])%28];
ww[36]=rr[(15+bb[i])%28];ww[37]=rr[(20+bb[i])%28];ww[38]=rr[(10+bb[i])%28];ww[39]=rr[(bb[i]-1)%28];ww[40]=rr[(5+bb[i])%28];ww[41]=rr[(24+bb[i])%28];
ww[42]=rr[(17+bb[i])%28];ww[43]=rr[(13+bb[i])%28];ww[44]=rr[(21+bb[i])%28];ww[45]=rr[(7+bb[i])%28];ww[46]=rr[(0+bb[i])%28];ww[47]=rr[(3+bb[i])%28];
ww[48]='\0';
最后,ww字符数组存的就是置换选择2后生成的子密钥。
啦啦啦,就是这样,我觉得我的方法就是最粗暴的办法了,忘各位大佬勿喷。有要讨论的可以加群
435982304,备注csdn,我就会同意