本人能力有限,這個僅供參考,請各位注意
*這僅是DES的第一輪加密
*輸入明文:computer#
*輸入密文:program#
*書本的錯誤:
*1.密鑰k經過置換後得到的D0最後一位有錯誤,應該為1 (這個錯誤不影響往後的結果)
*2.通過8個s盒得到32位的序列第二組前四位有錯,應該為1101,而不是0011
*3.往後的結果均由上2的錯誤導致
********************************************/
/********DES密碼的加密過程******************
*1.將字母轉化為二進制數(明文&密文)分成兩組完成
*2.對明文m進行初始IP置換完成
*3.對密鑰k進行密鑰置換完成
*4.對密鑰k進行壓縮置換完成
*5.對R0進行擴展變換32->48完成
*6.結果和k進行異或運算完成
*7.將結果分成8組,通過8個s盒完成
*8.對s盒的輸出序列進行P置換完成
*9.對p置換的結果與L0進行異或運算完成
********************************************/
#include
int ip[] = {//IP置換
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
};
int jiou[] = {
7,15,23,31,39,47,55,63//進行密鑰添加奇偶校驗位使用
};
int ki[] = {//密鑰置換
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
};
int kyasuo[]= {//對密鑰進行壓縮置換
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
};
int mkuozhan[]= {
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
};
int s[8][4][16] = {//8個s盒
{
{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}
},
{
{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, 4,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}
},
{
{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}
},
{
{ 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}
},
{
{ 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},
{10, 6, 9, 0,12,11, 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}
},
{
{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}
},
{
{ 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}
},
{
{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}
}
};
int p[32] = {//最後的p置換
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
};
void main()
{
char mingwen1[100];
int mingwen2[100];
int tempmingwen[100];
int L0[32],R0[32];
int R48[48];
char miyue1[100];
int miyue2[100];
int tempmiyue[100];
int C0[28],D0[28];
int yihuo[48];//存放R0與K1異或的結果
int sheD; //存放經過s盒之後的十進制結果
int sheB[8][4];//存放經過s盒之後的二進制結果
int she[32];//對s盒中的數據進行合併,存放經過s盒的結果
int hang,lie;//存放s盒的行列序號
int p2[32];//存放經過p置換後的結果
int c,d;//存放C0[0]和D0[0]
int i,j;//i,j作為循環使用
int icount1,icount2,k;
int temp;
//__________________________明文輸入__________________________________________________________________________________________________
k=0;
printf("請輸入明文(以'#'號結尾):\n");
for(i=0; i<100; i++)
{
scanf("%c",&mingwen1[i]);
if('#' == mingwen1[i])
{
icount1 = i;
goto loop1;
}
}
loop1:for(i=0;i<=icount1;i++)
{
for(j=7;j>=0;j--)
{
temp=mingwen1[i]&(1<
if(0 == temp)
{
mingwen2[k]=0;
k++;
}
else
{
mingwen2[k]=1;
k++;
}
}
}
//_________________________密鑰輸入___________________________________________________________________________________________________
k=0;
fflush(stdin);//清除緩衝區內的數據,如果不加上,則miwen[0]會多出一個LF(換行符)!!!
printf("請輸入密鑰(以'#'號結束):\n");
for(i=0; i<100; i++)
{
scanf("%c",&miyue1[i]);
if('#' == miyue1[i])
{
icount2 = i;
goto loop2;
}
}
loop2:for(i=0;i<=icount2;i++)
{
for(j=7;j>=0;j--)
{
temp=miyue1[i]&(1<
if(0 == temp)
{
miyue2[k]=0;
k++;
}
else
{
miyue2[k]=1;
k++;
}
}
}
//**********************************************************
printf("\n\nm = ");
for(i=0;i<8*icount1;i++)
{
printf("%d",mingwen2[i]);
if(i== 7 i==15 i==23 i==39 i==47 i==55 i==63)
{printf(" ");}
if(i==31)
{printf("\n");printf(" ");}
}
printf("\nk = ");
for(i=0;i<8*icount2;i++)
{
printf("%d",miyue2[i]);
if(i== 7 i==15 i==23 i==39 i==47 i==55 i==63)
{printf(" ");}
if(i==31)
{printf("\n");printf(" ");}
}
printf("\n");
//**********************************************************/
//____________________至此二進制的明文存放在mingwen2[]中_____________________________________________________________________________
//________________________進行明文的初始置換IP_________________________________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<8*icount1;i++)
{
tempmingwen[i] = mingwen2[ip[i]-1];
}
//________________________置換IP後的結果存放在tempmingwen[i]中__________________________________________________________________________
//________________________把明文結果存放到L0和R0中______________________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<64;i++)
{
if(i<32) {L0[i]=tempmingwen[i];}
else {R0[i-32]=tempmingwen[i];}
}
//**************************************
printf("\nm經過IP置換後得到:\n");
printf("L0: ");
for(i=0;i<32;i++)
{
printf("%d",L0[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
printf("\nR0: ");
for(i=0;i<32;i++)
{
printf("%d",R0[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
printf("\n");
//**************************************/
//_______________________對密文進行添加奇偶校驗位_______________________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<8;i++)
{
j=56+i;
while(j>=jiou[i])
{
miyue2[j+1]=miyue2[j];
j--;
}
if(i==0 i==2 i==4 i==6) {miyue2[jiou[i]]=0;}
else {miyue2[jiou[i]]=1;}
}
/**********************************************************
for(i=0;i<64;i++)
{
printf("%d",miyue2[i]);
if(i== 7 i==15 i==23 i==31 i==39 i==47 i==55 i==63)
{printf(" ");}
}
**********************************************************/
//_________________________對密文進行密鑰置換___________________________________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<56;i++)
{
tempmiyue[i]=miyue2[ki[i]-1];
}
/*********************************
printf("\n\n");
for(i=0;i<56;i++)
{
printf("%d",tempmiyue[i]);
if(i== 7 i==15 i==23 i==31 i==39 i==47 i==55 i==63)
{printf(" ");}
}
*********************************/
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<56;i++)
{
if(i<28) {C0[i]=tempmiyue[i];}
else {D0[i-28]=tempmiyue[i];}
}
//**************************************
printf("\n密鑰k經過置換後得到:");
printf("\nC0: ");
for(i=0;i<28;i++)
{
printf("%d",C0[i]);
if(i== 7 i==15 i==23)
{printf(" ");}
}
printf("\nR0: ");
for(i=0;i<28;i++)
{
printf("%d",D0[i]);
if(i== 7 i==15 i==23)
{printf(" ");}
}
printf("\n");
//**************************************/
//_________________________分別對C0和D0進行循環左移操作____________________________________________________________________________________
c = C0[0];
d = D0[0];
for(i=0;i<27;i++)
{
C0[i] = C0[i+1];
}
C0[28] = c;
for(i=0;i<27;i++)
{
D0[i] = D0[i+1];
}
D0[28] = d;
//__________________________對C0和D0進行合併存入miyue2[]中______________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<56;i++)
{
if(i<28) {miyue2[i]=C0[i];}
else {miyue2[i]=D0[i-28];}
}
//______________________________________________________________________________________-
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<48;i++)
{
tempmiyue[i] = miyue2[kyasuo[i]-1];
}
//**************************************
printf("\n循環左移一位後經過密鑰置換得到48位子密鑰:\n");
for(i=0;i<48;i++)
{
printf("%d",tempmiyue[i]);
if(i== 7 i==15 i==31 i==39 i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<48;i++)
{
R48[i]=R0[mkuozhan[i]-1];
}
//***************************************
printf("\n\nR0經過擴展變換得到的48位序列為:\n");
for(i=0;i<48;i++)
{
printf("%d",R48[i]);
if(i== 7 i==15 i==31 i==39 i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
//______________________R0與K1異或______________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<48;i++)
{
yihuo[i] = R48[i]^tempmiyue[i];
}
//______________________結果存放到yihuo[]數組中_________________________________________________
//***************************************
printf("\n\n結果再和k1進行異或運算,得到的結果為:\n");
for(i=0;i<48;i++)
{
printf("%d",yihuo[i]);
if(i== 7 i==15 i==31 i==39 i==47)
{printf(" ");}
if(i==23)
{printf("\n");}
}
//**************************************/
//_______________________通過8個s盒的到32位的序列_______________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<8;i++)
{
k=0;//清除k的值
hang=yihuo[(1+(i*6))-1]*2 + yihuo[(6+(i*6))-1];
lie =yihuo[(2+(i*6))-1]*8 + yihuo[(3+(i*6))-1]*4 + yihuo[(4+(i*6))-1]*2 + yihuo[(5+(i*6))-1];
sheD=s[i][hang][lie];
for(j=3;j>=0;j--)
{
temp=sheD&(1<
if(0 == temp)
{
sheB[i][k]=0;
k++;
}
else
{
sheB[i][k]=1;
k++;
}
}
}
//______________________將二維數組sheB[][]中的內容轉存到一維數組she中,方便以後的計算___________
fflush(stdin);//清除緩衝區內的數據
k=0;
for(i=0;i<8;i++)
{
for(j=0;j<4;j++)
{
she[k]=sheB[i][j];
k++;
}
}
//*************************************
printf("\n\n通過8個s盒得到32位的序列為:\n");
for(i=0;i<32;i++)
{
printf("%d",she[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
printf("\n");
//*************************************/
//______________________對s盒的輸出序列進行p置換__________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<32;i++)
{
p2[i]=she[p[i]-1];
}
//*************************************
fflush(stdin);//清除緩衝區內的數據
printf("\n對s盒的輸出序列進行p置換,得到\n");
for(i=0;i<32;i++)
{
printf("%d",p2[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
//*************************************/
//______________________p置換之後和L0進行異或運算_______________________________________________________________________________
fflush(stdin);//清除緩衝區內的數據
for(i=0;i<32;i++)
{
p2[i]=L0[i]^p2[i];
}
//______________________L0和R0交換________________________________________________________________________________________________________
for(i=0;i<32;i++)
{
L0[i]=R0[i];
R0[i]=p2[i];
}
//*************************************
printf("\n\n經過以上操作,得到進過第一輪加密的結果序列為:\n");
printf("L0: ");
for(i=0;i<32;i++)
{
printf("%d",L0[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
printf("\n");
printf("R0: ");
for(i=0;i<32;i++)
{
printf("%d",R0[i]);
if(i== 7 i==15 i==23 i==31)
{printf(" ");}
}
printf("\n");
//*************************************/
}