實驗一:C語言實現DES加解密算法


計算程序執行10萬次需要的時間:

總共需要175秒

加解密一次的時間小於:0.00175秒

純計算加解密的時間會更短

去除IO操作后的時間

也就是說加解密一次的時間為0.07毫秒

  1 /*-------------------------------------------------------
  2 Data Encryption Standard  56位密鑰加密64位數據
  3 --------------------------------------------------------*/
  4 #include <stdlib.h>
  5 #include <stdio.h>
  6 #include <time.h>
  7 #include "bool.h"   // 位處理 
  8 #include "tables.h"
  9 
 10 void BitsCopy(bool *DatOut, bool *DatIn, int Len);  // 數組復制 
 11 
 12 void ByteToBit(bool *DatOut, char *DatIn, int Num); // 字節到位 
 13 void BitToByte(char *DatOut, bool *DatIn, int Num); // 位到字節
 14 
 15 void BitToHex(char *DatOut, bool *DatIn, int Num);  // 二進制到十六進制 64位 to 4*16字符
 16 void HexToBit(bool *DatOut, char *DatIn, int Num);  // 十六進制到二進制 
 17 
 18 void TablePermute(bool *DatOut, bool *DatIn, const char *Table, int Num); // 位表置換函數 
 19 void LoopMove(bool *DatIn, int Len, int Num);     // 循環左移 Len長度 Num移動位數 
 20 void Xor(bool *DatA, bool *DatB, int Num);         // 異或函數 
 21 
 22 void S_Change(bool DatOut[32], bool DatIn[48]);   // S盒變換 
 23 void F_Change(bool DatIn[32], bool DatKi[48]);    // F函數                                  
 24 
 25 void SetKey(char KeyIn[8]);                         // 設置密鑰
 26 void PlayDes(char MesOut[8], char MesIn[8]);       // 執行DES加密
 27 void KickDes(char MesOut[8], char MesIn[8]);             // 執行DES解密 
 28 
 29 
 30 
 31 int main()
 32 {
 33     clock_t aaa, bbb;
 34     int jjj = 0;
 35     aaa = time(NULL);
 36     while (jjj <100000)
 37     {
 38     int i = 0;
 39     char MesHex[16] = { 0 };         // 16個字符數組用於存放 64位16進制的密文
 40     char MyKey[8] = { 0 };           // 初始密鑰 8字節*8
 41     char YourKey[8] = { 0 };         // 輸入的解密密鑰 8字節*8
 42     char MyMessage[8] = { 0 };       // 初始明文 
 43 
 44     /*-----------------------------------------------*/
 45 
 46     printf("Welcome! Please input your Message(64 bit):\n");
 47     //gets(MyMessage);            // 明文
 48     MyMessage[0] = '1';
 49     MyMessage[1] = '2';
 50     MyMessage[2] = '3';
 51     MyMessage[3] = '4';
 52     MyMessage[4] = '5';
 53     MyMessage[5] = '6';
 54     MyMessage[6] = '7';
 55     MyMessage[7] = '8';
 56     //MyMessage[0] = '\0';
 57     printf("Please input your Secret Key:\n");
 58     MyKey[0] = '1';                // 密鑰
 59     MyKey[1] = '2';
 60     MyKey[2] = '3';
 61     MyKey[3] = '4';
 62     MyKey[4] = '5';
 63     MyKey[5] = '6';
 64     MyKey[6] = '7';
 65     MyKey[7] = '8';
 66     //MyKey[8] = '\0';
 67     while (MyKey[i] != '\0')        // 計算密鑰長度
 68     {
 69         i++;
 70     }
 71     /*
 72     while (i != 8)                  // 不是8 提示錯誤
 73     {
 74     printf("Please input a correct Secret Key!\n");
 75     gets(MyKey);
 76     i = 0;
 77     while (MyKey[i] != '\0')    // 再次檢測
 78     {
 79     i++;
 80     }
 81     }*/
 82 
 83     SetKey(MyKey);               // 設置密鑰 得到子密鑰Ki
 84 
 85     PlayDes(MesHex, MyMessage);   // 執行DES加密
 86 
 87     printf("Your Message is Encrypted!:\n");  // 信息已加密
 88     for (i = 0; i < 16; i++)
 89     {
 90         printf("%c ", MesHex[i]);
 91     }
 92     printf("\n\n");
 93 
 94     printf("Please input your Secret Key to Deciphering:\n");  // 請輸入密鑰以解密
 95     //gets(YourKey);                                         // 得到密鑰
 96     YourKey[0] = '1';
 97     YourKey[1] = '2';
 98     YourKey[2] = '3';
 99     YourKey[3] = '4';
100     YourKey[4] = '5';
101     YourKey[5] = '6';
102     YourKey[6] = '7';
103     YourKey[7] = '8';
104     //YourKey[8] = '\0';
105     SetKey(YourKey);                                       // 設置密鑰
106 
107     KickDes(MyMessage, MesHex);                     // 解密輸出到MyMessage
108 
109     printf("Deciphering Over !!:\n");                     // 解密結束
110     for (i = 0; i < 8; i++)
111     {
112         printf("%c ", MyMessage[i]);
113     }
114     printf("\n\n");
115 
116     jjj++;
117 }
118     bbb = time(NULL);
119     printf("bbb-aaa= %f",(double)(bbb - aaa));
120     system("pause");
121     /*------------------------------------------------*/
122 }
123 
124 /*-------------------------------
125 把DatIn開始的長度位Len位的二進制
126 復制到DatOut后
127 --------------------------------*/
128 void BitsCopy(bool *DatOut, bool *DatIn, int Len)     // 數組復制 OK 
129 {
130     int i = 0;
131     for (i = 0; i<Len; i++)
132     {
133         DatOut[i] = DatIn[i];
134     }
135 }
136 
137 /*-------------------------------
138 字節轉換成位函數
139 每8次換一個字節 每次向右移一位
140 和1與取最后一位 共64位
141 --------------------------------*/
142 void ByteToBit(bool *DatOut, char *DatIn, int Num)       // OK
143 {
144     int i = 0;
145     for (i = 0; i<Num; i++)
146     {
147         DatOut[i] = (DatIn[i / 8] >> (i % 8)) & 0x01;
148     }
149 }
150 
151 /*-------------------------------
152 位轉換成字節函數
153 字節數組每8次移一位
154 位每次向左移 與上一次或
155 ---------------------------------*/
156 void BitToByte(char *DatOut, bool *DatIn, int Num)        // OK
157 {
158     int i = 0;
159     for (i = 0; i<(Num / 8); i++)
160     {
161         DatOut[i] = 0;
162     }
163     for (i = 0; i<Num; i++)
164     {
165         DatOut[i / 8] |= DatIn[i] << (i % 8);
166     }
167 }
168 
169 
170 /*----------------------------------
171 二進制密文轉換為十六進制
172 需要16個字符表示
173 -----------------------------------*/
174 void BitToHex(char *DatOut, bool *DatIn, int Num)
175 {
176     int i = 0;
177     for (i = 0; i<Num / 4; i++)
178     {
179         DatOut[i] = 0;
180     }
181     for (i = 0; i<Num / 4; i++)
182     {
183         DatOut[i] = DatIn[i * 4] + (DatIn[i * 4 + 1] << 1)
184             + (DatIn[i * 4 + 2] << 2) + (DatIn[i * 4 + 3] << 3);
185         if ((DatOut[i] % 16)>9)
186         {
187             DatOut[i] = DatOut[i] % 16 + '7';       //  余數大於9時處理 10-15 to A-F
188         }                                     //  輸出字符 
189         else
190         {
191             DatOut[i] = DatOut[i] % 16 + '0';       //  輸出字符       
192         }
193     }
194 
195 }
196 
197 /*---------------------------------------------
198 十六進制字符轉二進制
199 ----------------------------------------------*/
200 void HexToBit(bool *DatOut, char *DatIn, int Num)
201 {
202     int i = 0;                        // 字符型輸入 
203     for (i = 0; i<Num; i++)
204     {
205         if ((DatIn[i / 4])>'9')         //  大於9 
206         {
207             DatOut[i] = ((DatIn[i / 4] - '7') >> (i % 4)) & 0x01;
208         }
209         else
210         {
211             DatOut[i] = ((DatIn[i / 4] - '0') >> (i % 4)) & 0x01;
212         }
213     }
214 }
215 
216 // 表置換函數  OK
217 void TablePermute(bool *DatOut, bool *DatIn, const char *Table, int Num)
218 {
219     int i = 0;
220     static bool Temp[256] = { 0 };
221     for (i = 0; i<Num; i++)                // Num為置換的長度 
222     {
223         Temp[i] = DatIn[Table[i] - 1];  // 原來的數據按對應的表上的位置排列 
224     }
225     BitsCopy(DatOut, Temp, Num);       // 把緩存Temp的值輸出 
226 }
227 
228 // 子密鑰的移位
229 void LoopMove(bool *DatIn, int Len, int Num) // 循環左移 Len數據長度 Num移動位數
230 {
231     static bool Temp[256] = { 0 };    // 緩存   OK
232     BitsCopy(Temp, DatIn, Num);       // 將數據最左邊的Num位(被移出去的)存入Temp 
233     BitsCopy(DatIn, DatIn + Num, Len - Num); // 將數據左邊開始的第Num移入原來的空間
234     BitsCopy(DatIn + Len - Num, Temp, Num);  // 將緩存中移出去的數據加到最右邊 
235 }
236 
237 // 按位異或
238 void Xor(bool *DatA, bool *DatB, int Num)           // 異或函數
239 {
240     int i = 0;
241     for (i = 0; i<Num; i++)
242     {
243         DatA[i] = DatA[i] ^ DatB[i];                  // 異或 
244     }
245 }
246 
247 // 輸入48位 輸出32位 與Ri異或
248 void S_Change(bool DatOut[32], bool DatIn[48])     // S盒變換
249 {
250     int i, X, Y;                                    // i為8個S盒 
251     for (i = 0, Y = 0, X = 0; i<8; i++, DatIn += 6, DatOut += 4)   // 每執行一次,輸入數據偏移6位 
252     {                                              // 每執行一次,輸出數據偏移4位
253         Y = (DatIn[0] << 1) + DatIn[5];                          // af代表第幾行
254         X = (DatIn[1] << 3) + (DatIn[2] << 2) + (DatIn[3] << 1) + DatIn[4]; // bcde代表第幾列
255         ByteToBit(DatOut, &S_Box[i][Y][X], 4);      // 把找到的點數據換為二進制    
256     }
257 }
258 
259 // F函數
260 void F_Change(bool DatIn[32], bool DatKi[48])       // F函數
261 {
262     static bool MiR[48] = { 0 };             // 輸入32位通過E選位變為48位
263     TablePermute(MiR, DatIn, E_Table, 48);
264     Xor(MiR, DatKi, 48);                   // 和子密鑰異或
265     S_Change(DatIn, MiR);                 // S盒變換
266     TablePermute(DatIn, DatIn, P_Table, 32);   // P置換后輸出
267 }
268 
269 
270 
271 void SetKey(char KeyIn[8])               // 設置密鑰 獲取子密鑰Ki 
272 {
273     int i = 0;
274     static bool KeyBit[64] = { 0 };                // 密鑰二進制存儲空間 
275     static bool *KiL = &KeyBit[0], *KiR = &KeyBit[28];  // 前28,后28共56
276     ByteToBit(KeyBit, KeyIn, 64);                    // 把密鑰轉為二進制存入KeyBit 
277     TablePermute(KeyBit, KeyBit, PC1_Table, 56);      // PC1表置換 56次
278     for (i = 0; i<16; i++)
279     {
280         LoopMove(KiL, 28, Move_Table[i]);       // 前28位左移 
281         LoopMove(KiR, 28, Move_Table[i]);          // 后28位左移 
282         TablePermute(SubKey[i], KeyBit, PC2_Table, 48);
283         // 二維數組 SubKey[i]為每一行起始地址 
284         // 每移一次位進行PC2置換得 Ki 48位 
285     }
286 }
287 
288 void PlayDes(char MesOut[8], char MesIn[8])  // 執行DES加密
289 {                                           // 字節輸入 Bin運算 Hex輸出 
290     int i = 0;
291     static bool MesBit[64] = { 0 };        // 明文二進制存儲空間 64位
292     static bool Temp[32] = { 0 };
293     static bool *MiL = &MesBit[0], *MiR = &MesBit[32]; // 前32位 后32位 
294     ByteToBit(MesBit, MesIn, 64);                 // 把明文換成二進制存入MesBit
295     TablePermute(MesBit, MesBit, IP_Table, 64);    // IP置換 
296     for (i = 0; i<16; i++)                       // 迭代16次 
297     {
298         BitsCopy(Temp, MiR, 32);            // 臨時存儲
299         F_Change(MiR, SubKey[i]);           // F函數變換
300         Xor(MiR, MiL, 32);                  // 得到Ri 
301         BitsCopy(MiL, Temp, 32);            // 得到Li 
302     }
303     TablePermute(MesBit, MesBit, IPR_Table, 64);
304     BitToHex(MesOut, MesBit, 64);
305 }
306 
307 void KickDes(char MesOut[8], char MesIn[8])       // 執行DES解密
308 {                                                // Hex輸入 Bin運算 字節輸出 
309     int i = 0;
310     static bool MesBit[64] = { 0 };        // 密文二進制存儲空間 64位
311     static bool Temp[32] = { 0 };
312     static bool *MiL = &MesBit[0], *MiR = &MesBit[32]; // 前32位 后32位
313     HexToBit(MesBit, MesIn, 64);                 // 把密文換成二進制存入MesBit
314     TablePermute(MesBit, MesBit, IP_Table, 64);    // IP置換 
315     for (i = 15; i >= 0; i--)
316     {
317         BitsCopy(Temp, MiL, 32);
318         F_Change(MiL, SubKey[i]);
319         Xor(MiL, MiR, 32);
320         BitsCopy(MiR, Temp, 32);
321     }
322     TablePermute(MesBit, MesBit, IPR_Table, 64);
323     BitToByte(MesOut, MesBit, 64);
324 }
main2.c

驗證算法的正確性和雪崩現象

1.

明文:12345678

密鑰:12345678

密文:6E15D7EC4F9D4A06

2.修改一位明文

明文:12345679

密鑰:12345678

密文:48598F155CB7C5C9

3.修改一位密鑰

明文:12345678

密鑰:12345679

密文:02AB45B02D446190

-main.c

  1 /*-------------------------------------------------------
  2       Data Encryption Standard  56位密鑰加密64位數據
3 --------------------------------------------------------*/ 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include "bool.h" // 位處理 7 #include "tables.h" 8 9 void BitsCopy(bool *DatOut,bool *DatIn,int Len); // 數組復制 10 11 void ByteToBit(bool *DatOut,char *DatIn,int Num); // 字節到位 12 void BitToByte(char *DatOut,bool *DatIn,int Num); // 位到字節 13 14 void BitToHex(char *DatOut,bool *DatIn,int Num); // 二進制到十六進制 64位 to 4*16字符 15 void HexToBit(bool *DatOut,char *DatIn,int Num); // 十六進制到二進制 16 17 void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num); // 位表置換函數 18 void LoopMove(bool *DatIn,int Len,int Num); // 循環左移 Len長度 Num移動位數 19 void Xor(bool *DatA,bool *DatB,int Num); // 異或函數 20 21 void S_Change(bool DatOut[32],bool DatIn[48]); // S盒變換 22 void F_Change(bool DatIn[32],bool DatKi[48]); // F函數 23 24 void SetKey(char KeyIn[8]); // 設置密鑰 25 void PlayDes(char MesOut[8],char MesIn[8]); // 執行DES加密 26 void KickDes(char MesOut[8],char MesIn[8]); // 執行DES解密 27 28 29 30 int main() 31 { 32 int i=0; 33 char MesHex[16]={0}; // 16個字符數組用於存放 64位16進制的密文 34 char MyKey[8]={0}; // 初始密鑰 8字節*8 35 char YourKey[8]={0}; // 輸入的解密密鑰 8字節*8 36 char MyMessage[8]={0}; // 初始明文 37 38 /*-----------------------------------------------*/ 39 40 printf("Welcome! Please input your Message(64 bit):\n"); 41 gets(MyMessage); // 明文 42 printf("Please input your Secret Key:\n"); 43 gets(MyKey); // 密鑰 44 45 while(MyKey[i]!='\0') // 計算密鑰長度 46 { 47 i++; 48 } 49 50 while(i!=8) // 不是8 提示錯誤 51 { 52 printf("Please input a correct Secret Key!\n"); 53 gets(MyKey); 54 i=0; 55 while(MyKey[i]!='\0') // 再次檢測 56 { 57 i++; 58 } 59 } 60 61 SetKey(MyKey); // 設置密鑰 得到子密鑰Ki 62 63 PlayDes(MesHex,MyMessage); // 執行DES加密 64 65 printf("Your Message is Encrypted!:\n"); // 信息已加密 66 for(i=0;i<16;i++) 67 { 68 printf("%c ",MesHex[i]); 69 } 70 printf("\n\n"); 71 72 printf("Please input your Secret Key to Deciphering:\n"); // 請輸入密鑰以解密 73 gets(YourKey); // 得到密鑰 74 SetKey(YourKey); // 設置密鑰 75 76 KickDes(MyMessage,MesHex); // 解密輸出到MyMessage 77 78 printf("Deciphering Over !!:\n"); // 解密結束 79 for(i=0;i<8;i++) 80 { 81 printf("%c ",MyMessage[i]); 82 } 83 printf("\n\n"); 84 85 /*------------------------------------------------*/ 86 } 87 88 /*------------------------------- 89 把DatIn開始的長度位Len位的二進制 90 復制到DatOut后 91 --------------------------------*/ 92 void BitsCopy(bool *DatOut,bool *DatIn,int Len) // 數組復制 OK 93 { 94 int i=0; 95 for(i=0;i<Len;i++) 96 { 97 DatOut[i]=DatIn[i]; 98 } 99 } 100 101 /*------------------------------- 102 字節轉換成位函數 103 每8次換一個字節 每次向右移一位 104 和1與取最后一位 共64位 105 --------------------------------*/ 106 void ByteToBit(bool *DatOut,char *DatIn,int Num) // OK 107 { 108 int i=0; 109 for(i=0;i<Num;i++) 110 { 111 DatOut[i]=(DatIn[i/8]>>(i%8))&0x01; 112 } 113 } 114 115 /*------------------------------- 116 位轉換成字節函數 117 字節數組每8次移一位 118 位每次向左移 與上一次或 119 ---------------------------------*/ 120 void BitToByte(char *DatOut,bool *DatIn,int Num) // OK 121 { 122 int i=0; 123 for(i=0;i<(Num/8);i++) 124 { 125 DatOut[i]=0; 126 } 127 for(i=0;i<Num;i++) 128 { 129 DatOut[i/8]|=DatIn[i]<<(i%8); 130 } 131 } 132 133 134 /*---------------------------------- 135 二進制密文轉換為十六進制 136 需要16個字符表示 137 -----------------------------------*/ 138 void BitToHex(char *DatOut,bool *DatIn,int Num) 139 { 140 int i=0; 141 for(i=0;i<Num/4;i++) 142 { 143 DatOut[i]=0; 144 } 145 for(i=0;i<Num/4;i++) 146 { 147 DatOut[i] = DatIn[i*4]+(DatIn[i*4+1]<<1) 148 +(DatIn[i*4+2]<<2)+(DatIn[i*4+3]<<3); 149 if((DatOut[i]%16)>9) 150 { 151 DatOut[i]=DatOut[i]%16+'7'; // 余數大於9時處理 10-15 to A-F 152 } // 輸出字符 153 else 154 { 155 DatOut[i]=DatOut[i]%16+'0'; // 輸出字符 156 } 157 } 158 159 } 160 161 /*--------------------------------------------- 162 十六進制字符轉二進制 163 ----------------------------------------------*/ 164 void HexToBit(bool *DatOut,char *DatIn,int Num) 165 { 166 int i=0; // 字符型輸入 167 for(i=0;i<Num;i++) 168 { 169 if((DatIn[i/4])>'9') // 大於9 170 { 171 DatOut[i]=((DatIn[i/4]-'7')>>(i%4))&0x01; 172 } 173 else 174 { 175 DatOut[i]=((DatIn[i/4]-'0')>>(i%4))&0x01; 176 } 177 } 178 } 179 180 // 表置換函數 OK 181 void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num) 182 { 183 int i=0; 184 static bool Temp[256]={0}; 185 for(i=0;i<Num;i++) // Num為置換的長度 186 { 187 Temp[i]=DatIn[Table[i]-1]; // 原來的數據按對應的表上的位置排列 188 } 189 BitsCopy(DatOut,Temp,Num); // 把緩存Temp的值輸出 190 } 191 192 // 子密鑰的移位 193 void LoopMove(bool *DatIn,int Len,int Num) // 循環左移 Len數據長度 Num移動位數 194 { 195 static bool Temp[256]={0}; // 緩存 OK 196 BitsCopy(Temp,DatIn,Num); // 將數據最左邊的Num位(被移出去的)存入Temp 197 BitsCopy(DatIn,DatIn+Num,Len-Num); // 將數據左邊開始的第Num移入原來的空間 198 BitsCopy(DatIn+Len-Num,Temp,Num); // 將緩存中移出去的數據加到最右邊 199 } 200 201 // 按位異或 202 void Xor(bool *DatA,bool *DatB,int Num) // 異或函數 203 { 204 int i=0; 205 for(i=0;i<Num;i++) 206 { 207 DatA[i]=DatA[i]^DatB[i]; // 異或 208 } 209 } 210 211 // 輸入48位 輸出32位 與Ri異或 212 void S_Change(bool DatOut[32],bool DatIn[48]) // S盒變換 213 { 214 int i,X,Y; // i為8個S盒 215 for(i=0,Y=0,X=0;i<8;i++,DatIn+=6,DatOut+=4) // 每執行一次,輸入數據偏移6位 216 { // 每執行一次,輸出數據偏移4位 217 Y=(DatIn[0]<<1)+DatIn[5]; // af代表第幾行 218 X=(DatIn[1]<<3)+(DatIn[2]<<2)+(DatIn[3]<<1)+DatIn[4]; // bcde代表第幾列 219 ByteToBit(DatOut,&S_Box[i][Y][X],4); // 把找到的點數據換為二進制 220 } 221 } 222 223 // F函數 224 void F_Change(bool DatIn[32],bool DatKi[48]) // F函數 225 { 226 static bool MiR[48]={0}; // 輸入32位通過E選位變為48位 227 TablePermute(MiR,DatIn,E_Table,48); 228 Xor(MiR,DatKi,48); // 和子密鑰異或 229 S_Change(DatIn,MiR); // S盒變換 230 TablePermute(DatIn,DatIn,P_Table,32); // P置換后輸出 231 } 232 233 234 235 void SetKey(char KeyIn[8]) // 設置密鑰 獲取子密鑰Ki 236 { 237 int i=0; 238 static bool KeyBit[64]={0}; // 密鑰二進制存儲空間 239 static bool *KiL=&KeyBit[0],*KiR=&KeyBit[28]; // 前28,后28共56 240 ByteToBit(KeyBit,KeyIn,64); // 把密鑰轉為二進制存入KeyBit 241 TablePermute(KeyBit,KeyBit,PC1_Table,56); // PC1表置換 56次 242 for(i=0;i<16;i++) 243 { 244 LoopMove(KiL,28,Move_Table[i]); // 前28位左移 245 LoopMove(KiR,28,Move_Table[i]); // 后28位左移 246 TablePermute(SubKey[i],KeyBit,PC2_Table,48); 247 // 二維數組 SubKey[i]為每一行起始地址 248 // 每移一次位進行PC2置換得 Ki 48位 249 } 250 } 251 252 void PlayDes(char MesOut[8],char MesIn[8]) // 執行DES加密 253 { // 字節輸入 Bin運算 Hex輸出 254 int i=0; 255 static bool MesBit[64]={0}; // 明文二進制存儲空間 64位 256 static bool Temp[32]={0}; 257 static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位 后32位 258 ByteToBit(MesBit,MesIn,64); // 把明文換成二進制存入MesBit 259 TablePermute(MesBit,MesBit,IP_Table,64); // IP置換 260 for(i=0;i<16;i++) // 迭代16次 261 { 262 BitsCopy(Temp,MiR,32); // 臨時存儲 263 F_Change(MiR,SubKey[i]); // F函數變換 264 Xor(MiR,MiL,32); // 得到Ri 265 BitsCopy(MiL,Temp,32); // 得到Li 266 } 267 TablePermute(MesBit,MesBit,IPR_Table,64); 268 BitToHex(MesOut,MesBit,64); 269 } 270 271 void KickDes(char MesOut[8],char MesIn[8]) // 執行DES解密 272 { // Hex輸入 Bin運算 字節輸出 273 int i=0; 274 static bool MesBit[64]={0}; // 密文二進制存儲空間 64位 275 static bool Temp[32]={0}; 276 static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位 后32位 277 HexToBit(MesBit,MesIn,64); // 把密文換成二進制存入MesBit 278 TablePermute(MesBit,MesBit,IP_Table,64); // IP置換 279 for(i=15;i>=0;i--) 280 { 281 BitsCopy(Temp,MiL,32); 282 F_Change(MiL,SubKey[i]); 283 Xor(MiL,MiR,32); 284 BitsCopy(MiR,Temp,32); 285 } 286 TablePermute(MesBit,MesBit,IPR_Table,64); 287 BitToByte(MesOut,MesBit,64); 288 }

-tables.h

  1 /*-------------------------------------------------------------
  2         置換表 
  3 -------------------------------------------------------------*/
  4 
  5 #ifndef _TABLES_H_    // 防重復編譯 
  6 #define _TABLES_H_  
  7 
  8 // 對明文執行IP置換得到L0,R0 (L左32位,R右32位)               [明文操作]
  9 const char IP_Table[64]={             
 10     58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
 11     62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
 12     57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
 13     61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7 
 14 };
 15 
 16 // 對迭代后的L16,R16執行IP逆置換,輸出密文
 17 const char IPR_Table[64]={              
 18     40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
 19     38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
 20     36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
 21     34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25    
 22 };
 23 
 24 /*--------------------------- 迭代法則 ----------------------------*/ 
 25 
 26 // F函數,32位的R0進行E變換,擴為48位輸出 (R1~R16)        [備用A]  [明文操作] 
 27 static char E_Table[48]={
 28     32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
 29      8, 9,10,11,12,13,12,13,14,15,16,17,
 30     16,17,18,19,20,21,20,21,22,23,24,25,
 31     24,25,26,27,28,29,28,29,30,31,32, 1
 32 };
 33 
 34 // 子密鑰K(i)的獲取 密鑰為K 拋棄第6,16,24,32,40,48,64位          [密鑰操作] 
 35 // 用PC1選位 分為 前28位C0,后28位D0 兩部分  
 36 static char PC1_Table[56]={
 37     57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
 38     10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
 39     63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
 40     14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4
 41 };
 42 
 43 // 對C0,D0分別進行左移,共16次,左移位數與下面對應                 [密鑰操作]
 44 static char Move_Table[16]={
 45      1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
 46 };
 47 
 48 // C1,D1為第一次左移后得到,進行PC2選位,得到48位輸出K1   [備用B]   [密鑰操作]     
 49 static char PC2_Table[48]={
 50     14,17,11,24, 1, 5, 3,28,15, 6,21,10,
 51     23,19,12, 4,26, 8,16, 7,27,20,13, 2,
 52     41,52,31,37,47,55,30,40,51,34,33,48,
 53     44,49,39,56,34,53,46,42,50,36,29,32    
 54 };
 55 
 56 /*------------- F函數 備用A和備用B 異或 得到48位輸出 ---------------*/ 
 57 
 58 // 異或后的結果48位分為8組,每組6位,作為8個S盒的輸入             [組合操作] 
 59 // S盒以6位作為輸入(8組),4位作為輸出(4*(8組)=32位)
 60 // S工作原理 假設輸入為A=abcdef ,則bcde所代表的數是0-15之間的
 61 // 一個數記為 X=bcde ,af代表的是0-3之間的一個數,記為 Y=af 
 62 // 在S1的X列,Y行找到一個數Value,它在0-15之間,可以用二進制表示
 63 // 所以為4bit (共32位)  
 64 static char S_Box[8][4][16]={
 65     //S1
 66     14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
 67      0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
 68      4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
 69     15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
 70     //S2
 71     15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
 72      3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
 73      0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
 74     13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
 75     //S3
 76     10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
 77     13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
 78     13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
 79      1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
 80     //S4
 81      7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
 82     13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
 83     10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
 84      3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
 85     //S5
 86      2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
 87     14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
 88      4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
 89     11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
 90     //S6
 91     12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
 92     10,15, 4, 2, 7,12, 0, 5, 6, 1,13,14, 0,11, 3, 8,
 93      9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
 94         4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
 95     //S7
 96      4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
 97     13, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,
 98      1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
 99      6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
100     //S8
101     13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
102      1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
103      7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
104      2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11
105 };
106 
107 // F函數 最后第二步,對S盒輸出的32進行P置換                     [組合操作]
108 // 輸出的值參與一次迭代:
109 // L(i)=R(i-1)
110 // R(i)=L(i-1)^f(R(i-1),K(i)) 異或 
111 static char P_Table[32]={
112     16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
113      2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25
114 };
115 
116 // 16個子密鑰K(1~16) 
117 static bool SubKey[16][48]={0};
118 
119 #endif

-bool.h

 1 #ifndef __BOOL_H__
 2 #define __BOOL_H__
 3 
 4 typedef enum
 5   {
 6     false = 0,
 7     true  = 1
 8   } bool;
 9 
10 #endif

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM