DES加密解密算法C語言代碼實現

代碼:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 /*------------------------
  5      定義枚舉型全局變量
  6 ------------------------*/
  7 typedef enum
  8   {
  9     false = 0,
 10     true  = 1
 11   } bool;
 12   
 13   // 十六輪子密鑰
 14 static bool SubKey[16][48]={0};
 15   
 16  /*---------------------*/
 17 /*-------------------------------------------------------------
 18      各種置換表
 19 -------------------------------------------------------------*/
 20 // IP置換表
 21 const char IP_Table[64]={             
 22  58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
 23  62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
 24  57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
 25  61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7 
 26 };
 27 // IP-1置換表
 28 const char IPR_Table[64]={              
 29  40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
 30  38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
 31  36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
 32  34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25 
 33 };
 34 
 35 // E擴展表
 36 static char E_Table[48]={
 37  32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
 38   8, 9,10,11,12,13,12,13,14,15,16,17,
 39     16,17,18,19,20,21,20,21,22,23,24,25,
 40     24,25,26,27,28,29,28,29,30,31,32, 1
 41 };
 42 // PC1置換表
 43 static char PC1_Table[56]={
 44  57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
 45  10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
 46  63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
 47  14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4
 48 };
 49 
 50 // pc2表     
 51 static char PC2_Table[48]={
 52  14,17,11,24, 1, 5, 3,28,15, 6,21,10,
 53  23,19,12, 4,26, 8,16, 7,27,20,13, 2,
 54  41,52,31,37,47,55,30,40,51,34,33,48,
 55  44,49,39,56,34,53,46,42,50,36,29,32 
 56 };
 57 //  移位表
 58 static char Move_Table[16]={
 59   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
 60 };
 61  // S盒
 62 static char S_Box[8][4][16]={
 63  //S1
 64  14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
 65   0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
 66   4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
 67  15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
 68  //S2
 69  15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
 70   3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
 71   0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
 72  13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
 73  //S3
 74  10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
 75  13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
 76  13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
 77   1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
 78  //S4
 79   7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
 80  13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
 81  10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
 82   3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
 83  //S5
 84   2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
 85  14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
 86   4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
 87  11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
 88  //S6
 89  12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
 90  10,15, 4, 2, 7,12, 0, 5, 6, 1,13,14, 0,11, 3, 8,
 91   9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
 92      4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
 93  //S7
 94   4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
 95  13, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,
 96   1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
 97   6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
 98  //S8
 99  13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
100   1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
101   7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
102   2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11
103 };
104  //P置換表
105 static char P_Table[32]={
106  16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
107   2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
108 };
109 /*-------------------------------------------------------------------*/
110  
111 /*-----------------------------自定義函數-----------------------------*/
112 void SetKey(char My_key[8]); //生成16輪的子密鑰;
113 void ByteToBit(bool * Data_out,char * Data_in,int Num); //字節轉換成位;
114 void Change_bit(bool * Data_out,int Num);//二進制的位置進行轉換;
115 void BitToByte(char My_message[8],bool * Message_in,int Num); //位轉換成字節;
116 void TableReplace(bool *Data_out,bool *Data_in,const char *Table,int Num);  //各種表的置換算法;
117 void Bitcopy(bool * Data_out,bool * Data_in,int Num);  //二進制數組的拷貝
118 void Loop_bit(bool * Data_out,int movstep,int len);  //左移位;
119 void Run_Des(char My_message[8],char HexMssage[16]);//des的輪加密算法
120 void Xor(bool * Message_out, bool * Message_in,int Num); //執行異或
121 void S_change(bool * Data_out, bool * Data_in);  // S盒變換;
122 void HexToBit(bool * Data_out,char * Data_in,int Num); // 十六進制轉二進制
123 void BitToHex(char * Data_out,bool * Data_in,int Num); //二進制轉換成十六進制;
124 void Run_desDes(char My_message[8],char HexMessage[16]);// DES輪解密算法;
125 
126 /*--------------------------*/
127 
128 /*--------------------------主函數----------------------------------*/
129 int main()
130 {
131  int i=0,j;
132  char My_key[8]={0};  //記錄加密密鑰;
133  char You_key[8]={0}; //解密密鑰
134  char My_message[8]={0}; //明文
135  char Message_hex[16]={0};//16進制的密文
136  printf("請輸入你要加密的內容(8 Byte):\n");
137  gets(My_message);
138  printf("請輸入你的加密密鑰:\n");
139  gets(My_key);
140  i=strlen(My_key);
141  while(i!=8)
142  {
143   printf("請輸入加密密鑰(8 Byte)\n");
144   gets(My_key);
145   i=0;
146   i=strlen(My_key);
147  }
148  SetKey(My_key);  //生成16輪的加密子密鑰; 
149  Run_Des(My_message,Message_hex); //des的輪加密過程
150  printf("經過加密的密文爲:\n");
151  for(i=0;i<16;i++)
152  {
153   printf("%c ",Message_hex[i]);
154  }
155  printf("\n");
156  printf("請輸入你的解密密鑰(8 Byte):\n");
157  gets(You_key);
158  i=strlen(You_key);
159  while(i!=8)
160  {
161   printf("請輸入解密密鑰(8 Byte)\n");
162   gets(You_key);
163   i=0;
164   i=strlen(You_key);
165  }
166  SetKey(You_key);  //生成16輪的解密子密鑰;
167  Run_desDes(My_message,Message_hex);//解密;
168  printf("解密結果爲:\n");
169  for(i=0;i<8;i++)
170  {
171   printf("%c ",My_message[i]);
172  }
173  printf("\n");
174  return 0;
175 }
176 
177 /*--------------------具體函數定義----------------------*/
178 void Bitcopy(bool * Data_out, bool * Data_in,int Num) //二進制數組拷貝
179 {
180  int i=0;
181  for(i=0;i<Num;i++)
182  {  
183   Data_out[i]=Data_in[i];
184  }
185  
186 }
187 void Change_bit(bool * Data_out,int Num) //二進制的位置進行轉換;
188 {
189  int i,j;
190  static bool Temp[8]={0};
191  for(i=0;i<Num/8;i++)
192  {
193   Bitcopy(Temp,Data_out,Num/8);
194   for(j=0;j<Num/8;j++)
195   {
196    Data_out[j]=Temp[Num/8-1-j];
197   }
198   Data_out+=Num/8;
199  }
200 }
201 void ByteToBit( bool * Data_out,char * Data_in,int Num) //字節轉位
202 {
203  int i,j; 
204  for(i=0;i<Num;i++)
205  {
206   Data_out[i]=(Data_in[i/8]>>(i%8))&0x01;
207  }
208  //Change_bit(Data_out,Num);
209 }
210 void BitToHex(char * Data_out, bool * Data_in,int Num) //二進制轉十六進制
211 {
212  int i;
213  for(i=0;i<Num/4;i++)
214  {
215   Data_out[i]=0;
216  }
217  for(i=0;i<Num/4;i++)
218  {
219   Data_out[i]=Data_in[4*i]+Data_in[4*i+1]*2+Data_in[4*i+2]*4+Data_in[4*i+3]*8;
220   if(Data_out[i]%16>9)
221   {
222    Data_out[i]=Data_out[i]%16+'7';
223   }
224   else
225   Data_out[i]=Data_out[i]%16+'0';
226  }
227 }
228 void HexToBit(bool * Data_out,char * Data_in,int Num) //十六進制轉二進制
229 {
230  int i;
231  for(i=0;i<Num;i++)
232  {
233   if(Data_in[i/4]<='9')
234   {
235    Data_out[i]=((Data_in[i/4]-'0')>>(i%4))&0x01;
236   }
237   else
238   {
239    Data_out[i]=((Data_in[i/4]-'7')>>(i%4))&0x01;
240   }
241  }
242 }
243 void BitToByte(char My_message[8],bool * Message_in,int Num) //位轉換成字節
244 {
245  int i=0;
246  for(i=0;i<(Num/8);i++)
247  {
248   My_message[i]=0;
249  } 
250  for(i=0;i<Num;i++)
251  {
252   My_message[i/8]|=Message_in[i]<<(i%8); 
253  }  
254 }
255 void TableReplace( bool *Data_out, bool * Data_in,const char *Table ,int Num) // 置換算法
256 {
257  int i=0;
258  static bool Temp[256]={0};
259  for(i=0;i<Num;i++)
260  {
261   Temp[i]=Data_in[Table[i]-1];
262  }
263  Bitcopy(Data_out,Temp,Num);
264 }
265 void Loop_bit(bool * Data_out,int movstep,int len)
266 {
267  static bool Temp[256]={0};
268  Bitcopy(Temp,Data_out,movstep);
269  Bitcopy(Data_out,Data_out+movstep,len-movstep);
270  Bitcopy(Data_out+len-movstep,Temp,movstep);
271  /*Temp=Data_out;
272  Temp[movstep]='\0';
273  Data_out=Data_out+movstep;
274  Data_out+(len-movstep)=Temp;*/
275 }
276 void Xor(bool * Message_out,bool * Message_in,int Num)//執行異或
277 {
278  int i;
279  for(i=0;i<Num;i++)
280  {
281   Message_out[i]=Message_out[i]^Message_in[i];
282  }
283 }
284 void SetKey(char My_key[8])
285 {
286  int i,j;
287  static bool Key_bit[64]={0}; //Key的二進制緩存;
288  static bool *Key_bit_L,*Key_bit_R;
289  Key_bit_L=&Key_bit[0]; //key的左邊28位;
290  Key_bit_R=&Key_bit[28]; //key的右邊28位;
291  ByteToBit(Key_bit,My_key,64);
292 /* Change_bit(Key_bit,64) ;//二進制的位置進行轉換;
293  for(i=0;i<64;i++)
294  {
295   printf("%d ",Key_bit[i]);
296  }
297  printf("\n");
298  printf("\n");*/
299  TableReplace(Key_bit,Key_bit,PC1_Table,56);//pc-1 置換
300  for(i=0;i<16;i++)
301  {
302   Loop_bit(Key_bit_L,Move_Table[i],28);
303   Loop_bit(Key_bit_R,Move_Table[i],28);
304   TableReplace(SubKey[i],Key_bit,PC2_Table,48);//pc-2置換
305  }
306 }
307 void S_change(bool * Data_out, bool * Data_in) //S盒變換
308 {
309  int i;
310  int r=0,c=0;//S盒的行和列;
311  for(i=0;i<8;i++,Data_in=Data_in+6,Data_out=Data_out+4)
312  {
313   r=Data_in[0]*2+Data_in[5]*1;
314   c=Data_in[1]*8+Data_in[2]*4+Data_in[3]*2+Data_in[4]*1;
315   ByteToBit(Data_out,&S_Box[i][r][c],4);
316  } 
317 }
318 void F_change(bool Data_out[32],bool Data_in[48])   // f函數;
319 {
320  int i;
321  static bool Message_E[48]={0};  //存放E置換的結果;
322  TableReplace(Message_E,Data_out,E_Table,48);//E表置換
323  Xor(Message_E,Data_in,48);
324  S_change(Data_out,Message_E);                 // S盒變換
325  TableReplace(Data_out,Data_out,P_Table,32);  //P置換
326 }
327 void Run_Des(char My_message[8],char HexMssage[16])//des輪加密算法;
328 {
329  int i; 
330  static bool Message_bit[64]={0};
331  static bool *Message_bit_L=&Message_bit[0],*Message_bit_R=&Message_bit[32];
332  static bool Temp[32]={0};
333  ByteToBit(Message_bit,My_message,64);
334  /*Change_bit(Message_bit,64) ;//二進制的位置進行轉換;
335  for(i=0;i<64;i++)
336  {
337   printf("%d ",Message_bit[i]);
338  }
339  printf("\n");
340  printf("\n");*/
341  TableReplace(Message_bit,Message_bit,IP_Table,64);
342  for(i=0;i<16;i++)
343  {
344   Bitcopy(Temp,Message_bit_R,32);
345   F_change(Message_bit_R,SubKey[i]); 
346   Xor(Message_bit_R,Message_bit_L,32);
347   Bitcopy(Message_bit_L,Temp,32);
348  }
349  TableReplace(Message_bit,Message_bit,IPR_Table,64);
350  BitToHex(HexMssage,Message_bit,64);//二進制轉換成十六進制;
351 }
352 void Run_desDes(char My_message[8],char HexMessage[16])// DES輪解密算法;
353 {
354  int i=0;
355  static bool Message_bit[64]={0};
356  static bool * Message_bit_L=&Message_bit[0], * Message_bit_R=&Message_bit[32];
357  static bool Temp[32]={0};
358  HexToBit(Message_bit,HexMessage,64);
359  TableReplace(Message_bit,Message_bit,IP_Table,64);
360  for(i=15;i>=0;i--)
361  {
362   Bitcopy(Temp,Message_bit_L,32);
363   F_change(Message_bit_L,SubKey[i]); 
364   Xor(Message_bit_L,Message_bit_R,32);
365   Bitcopy(Message_bit_R,Temp,32);
366  }
367  TableReplace(Message_bit,Message_bit,IPR_Table,64);
368  BitToByte(My_message,Message_bit,64);
369 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章