实验一: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):
");
 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] = '';
 57     printf("Please input your Secret Key:
");
 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] = '';
 67     while (MyKey[i] != '')        // 计算密钥长度
 68     {
 69         i++;
 70     }
 71     /*
 72     while (i != 8)                  // 不是8 提示错误
 73     {
 74     printf("Please input a correct Secret Key!
");
 75     gets(MyKey);
 76     i = 0;
 77     while (MyKey[i] != '')    // 再次检测
 78     {
 79     i++;
 80     }
 81     }*/
 82 
 83     SetKey(MyKey);               // 设置密钥 得到子密钥Ki
 84 
 85     PlayDes(MesHex, MyMessage);   // 执行DES加密
 86 
 87     printf("Your Message is Encrypted!:
");  // 信息已加密
 88     for (i = 0; i < 16; i++)
 89     {
 90         printf("%c ", MesHex[i]);
 91     }
 92     printf("

");
 93 
 94     printf("Please input your Secret Key to Deciphering:
");  // 请输入密钥以解密
 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] = '';
105     SetKey(YourKey);                                       // 设置密钥
106 
107     KickDes(MyMessage, MesHex);                     // 解密输出到MyMessage
108 
109     printf("Deciphering Over !!:
");                     // 解密结束
110     for (i = 0; i < 8; i++)
111     {
112         printf("%c ", MyMessage[i]);
113     }
114     printf("

");
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): "); 41 gets(MyMessage); // 明文 42 printf("Please input your Secret Key: "); 43 gets(MyKey); // 密钥 44 45 while(MyKey[i]!='') // 计算密钥长度 46 { 47 i++; 48 } 49 50 while(i!=8) // 不是8 提示错误 51 { 52 printf("Please input a correct Secret Key! "); 53 gets(MyKey); 54 i=0; 55 while(MyKey[i]!='') // 再次检测 56 { 57 i++; 58 } 59 } 60 61 SetKey(MyKey); // 设置密钥 得到子密钥Ki 62 63 PlayDes(MesHex,MyMessage); // 执行DES加密 64 65 printf("Your Message is Encrypted!: "); // 信息已加密 66 for(i=0;i<16;i++) 67 { 68 printf("%c ",MesHex[i]); 69 } 70 printf(" "); 71 72 printf("Please input your Secret Key to Deciphering: "); // 请输入密钥以解密 73 gets(YourKey); // 得到密钥 74 SetKey(YourKey); // 设置密钥 75 76 KickDes(MyMessage,MesHex); // 解密输出到MyMessage 77 78 printf("Deciphering Over !!: "); // 解密结束 79 for(i=0;i<8;i++) 80 { 81 printf("%c ",MyMessage[i]); 82 } 83 printf(" "); 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
========================if i have some wrong, please give me a message, thx.========================
原文地址:https://www.cnblogs.com/ailx10/p/5303465.html