每日日报7——软件设计③|工厂方法模式(DES+IDEA)

一、工厂方法模式

https://baike.baidu.com/item/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F/2361103?fr=aladdin

二、版本

(一)C++版本:

① 类图:

② 效果:

 

③ 代码:

Main.cpp

  1 #include <iostream>
  2 #include <fstream>
  3 #include <bitset>
  4 #include <string>
  5 using namespace std;
  6 
  7 //define the type of data
  8 typedef unsigned char byte;
  9 typedef unsigned short word16;//16bit
 10 typedef unsigned long word32;//32bit
 11 
 12 bitset<64> key1;                // 64位密钥
 13 bitset<48> subKey[16];         // 存放16轮子密钥
 14 
 15 /*IDEA算法*/
 16 class idea
 17 {
 18 public:
 19     void setkey(byte in[]);
 20     void setplaintext(byte in[]);
 21     word16 invmul(word16 x);
 22     word16 mul(word16 x, word16 y);
 23     void encryption(word16 in[], word16 out[], word16* ek);
 24     void enc();
 25     void ideatest();
 26 
 27 private:
 28     void getencroundkey(word16* encroundkey);
 29     void getdecroundkey(word16* ek, word16 dk[]);
 30     byte key[16];
 31     word16 ciphertext[4];
 32     word16 plaintext[4];
 33     word16 deciphertext[4];
 34     word16 encroundkey[52];
 35     word16 decroundkey[52];
 36 };
 37 
 38 void idea::setplaintext(byte in[]) {
 39     //8个byte类型数据变成4个word16的数据
 40     int i;
 41     for (i = 0; i < 8; i += 2) {
 42         plaintext[i / 2] = (in[i] << 8) + in[i + 1];
 43     }
 44 }
 45 
 46 void idea::setkey(byte in[]) {
 47     int i;
 48     for (i = 0; i < 16; i++) {
 49         key[i] = in[i];
 50     }
 51     getencroundkey(encroundkey);
 52     getdecroundkey(encroundkey, decroundkey);
 53 }
 54 
 55 void idea::getencroundkey(word16* encroundkey) {
 56     int i, j;
 57     for (i = 0, j = 0; j < 8; j++) {
 58         encroundkey[j] = (key[i] << 8) + key[i + 1];
 59         i += 2;
 60     }
 61     for (i = 0; j < 52; j++) {
 62         i++;
 63         encroundkey[i + 7] = encroundkey[i & 7] << 9 | encroundkey[(i + 1) & 7] >> 7;
 64         encroundkey += (i & 8);
 65         i &= 7;
 66     }
 67 }
 68 
 69 void idea::getdecroundkey(word16* ek, word16 dk[]) {
 70     int i;
 71     word16 temp[52];
 72     word16 t1, t2, t3;
 73     word16* p = temp + 52;
 74     t1 = invmul(*ek++);
 75     t2 = -*ek++;
 76     t3 = -*ek++;
 77     *--p = invmul(*ek++);
 78     *--p = t3;
 79     *--p = t2;
 80     *--p = t1;
 81     for (i = 0; i < 7; i++) {
 82         t1 = *ek++;
 83         *--p = *ek++;
 84         *--p = t1;
 85         t1 = invmul(*ek++);
 86         t2 = -*ek++;
 87         t3 = -*ek++;
 88         *--p = invmul(*ek++);
 89         *--p = t2;
 90         *--p = t3;
 91         *--p = t1;
 92     }
 93     t1 = *ek++;
 94     *--p = *ek++;
 95     *--p = t1;
 96     t1 = invmul(*ek++);
 97     t2 = -*ek++;
 98     t3 = -*ek++;
 99     *--p = invmul(*ek++);
100     *--p = t3;
101     *--p = t2;
102     *--p = t1;
103     for (i = 0, p = temp; i < 52; i++) {
104         *ek++ = *p;
105         *p++ = 0;
106     }
107 }
108 
109 word16 idea::invmul(word16 x) {
110     word16 t0, t1;
111     word16 q, y;
112     if (x <= 1) {
113         return x;//0和1的逆是本身
114     }
115     t1 = word16(0x10001l / x);
116     y = word16(0x10001l % x);
117     if (y == 1) {
118         return (1 - t1) & 0xffff;
119     }
120     t0 = 1;
121     do {
122         q = x / y;
123         x = x % y;
124         t0 += q * t1;
125         if (x == 1) {
126             return t0;
127         }
128         q = y / x;
129         y = y % x;
130         t1 += q * t0;
131     } while (y != 1);
132     return (1 - t1) & 0xffff;
133 }
134 
135 void idea::encryption(word16 in[], word16 out[], word16* ek) {
136     word16 x1, x2, x3, x4, t1, t2;
137     x1 = in[0];
138     x2 = in[1];
139     x3 = in[2];
140     x4 = in[3];
141     int r = 8;
142     do {
143         x1 = mul(x1, *ek++);
144         x2 += *ek++;
145         x3 += *ek++;
146         x4 = mul(x4, *ek++);
147         t2 = x1 ^ x3;
148         t1 = x2 ^ x4;
149         t2 = mul(t2, *ek++);
150         t1 = t1 + t2;
151         t1 = mul(t1, *ek++);
152         t2 = t1 + t2;
153         x1 ^= t1;
154         x4 ^= t2;
155         t2 ^= x2;
156         x2 = x3 ^ t1;
157         x3 = t2;
158     } while (--r);
159     x1 = mul(x1, *ek++);
160     *out++ = x1;
161     *out++ = x3 + *ek++;
162     *out++ = x2 + *ek++;
163     x4 = mul(x4, *ek++);
164     *out = x4;
165 }
166 
167 word16 idea::mul(word16 x, word16 y) {
168     word32 p;
169     p = (word32)x * y;
170     if (p) {
171         y = p & 0xffff;
172         x = p >> 16;
173         return (y - x) + (y < x);
174     }
175     else if (x) {
176         return 1 - y;
177     }
178     else {
179         return 1 - x;
180     }
181 }
182 
183 void idea::enc() {
184     encryption(plaintext, ciphertext, encroundkey);
185     encryption(ciphertext, deciphertext, decroundkey);
186 }
187 
188 void idea::ideatest() {
189     ofstream fout("ideatest.txt");
190     fout << "the input key is:" << endl;
191     int i;
192     for (i = 0; i < 16; i++) {
193         fout << hex << int(key[i]) << " ";
194     }
195     fout << endl;
196     fout << "the plain text is:" << endl;
197     for (i = 0; i < 4; i++) {
198         fout << hex << plaintext[i] << " ";
199     }
200     fout << endl;
201     fout << "the ciphertext is:" << endl;
202     for (i = 0; i < 4; i++) {
203         fout << hex << ciphertext[i] << " ";
204     }
205     fout << endl;
206     fout << "the deciphertext is:" << endl;
207     for (i = 0; i < 4; i++) {
208         fout << hex << deciphertext[i] << " ";
209     }
210     fout << endl;
211 }
212 
213 /*DES算法*/
214 
215 // 初始置换表
216 int IP[] = { 58, 50, 42, 34, 26, 18, 10, 2,
217             60, 52, 44, 36, 28, 20, 12, 4,
218             62, 54, 46, 38, 30, 22, 14, 6,
219             64, 56, 48, 40, 32, 24, 16, 8,
220             57, 49, 41, 33, 25, 17, 9,  1,
221             59, 51, 43, 35, 27, 19, 11, 3,
222             61, 53, 45, 37, 29, 21, 13, 5,
223             63, 55, 47, 39, 31, 23, 15, 7 };
224 
225 // 结尾置换表
226 int IP_1[] = { 40, 8, 48, 16, 56, 24, 64, 32,
227               39, 7, 47, 15, 55, 23, 63, 31,
228               38, 6, 46, 14, 54, 22, 62, 30,
229               37, 5, 45, 13, 53, 21, 61, 29,
230               36, 4, 44, 12, 52, 20, 60, 28,
231               35, 3, 43, 11, 51, 19, 59, 27,
232               34, 2, 42, 10, 50, 18, 58, 26,
233               33, 1, 41,  9, 49, 17, 57, 25 };
234 
235 /*生成密钥所用表*/
236 // 密钥置换表,将64位密钥变成56位
237 int PC_1[] = { 57, 49, 41, 33, 25, 17, 9,
238                1, 58, 50, 42, 34, 26, 18,
239               10,  2, 59, 51, 43, 35, 27,
240               19, 11,  3, 60, 52, 44, 36,
241               63, 55, 47, 39, 31, 23, 15,
242                7, 62, 54, 46, 38, 30, 22,
243               14,  6, 61, 53, 45, 37, 29,
244               21, 13,  5, 28, 20, 12,  4 };
245 
246 // 压缩置换,将56位密钥压缩成48位子密钥
247 int PC_2[] = { 14, 17, 11, 24,  1,  5,
248                3, 28, 15,  6, 21, 10,
249               23, 19, 12,  4, 26,  8,
250               16,  7, 27, 20, 13,  2,
251               41, 52, 31, 37, 47, 55,
252               30, 40, 51, 45, 33, 48,
253               44, 49, 39, 56, 34, 53,
254               46, 42, 50, 36, 29, 32 };
255 
256 // 每轮左移的位数
257 int shiftBits[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
258 
259 /*密码函数 f 所用表*/
260 // 扩展置换表,将 32位 扩展至 48位
261 int E[] = { 32,  1,  2,  3,  4,  5,
262             4,  5,  6,  7,  8,  9,
263             8,  9, 10, 11, 12, 13,
264            12, 13, 14, 15, 16, 17,
265            16, 17, 18, 19, 20, 21,
266            20, 21, 22, 23, 24, 25,
267            24, 25, 26, 27, 28, 29,
268            28, 29, 30, 31, 32,  1 };
269 
270 // S盒,每个S盒是4x16的置换表,6位 -> 4位
271 int S_BOX[8][4][16] = {
272     {
273         {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
274         {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
275         {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
276         {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}
277     },
278     {
279         {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
280         {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
281         {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
282         {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}
283     },
284     {
285         {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
286         {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
287         {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
288         {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}
289     },
290     {
291         {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
292         {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
293         {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
294         {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}
295     },
296     {
297         {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
298         {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
299         {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
300         {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}
301     },
302     {
303         {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
304         {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
305         {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
306         {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}
307     },
308     {
309         {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
310         {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
311         {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
312         {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}
313     },
314     {
315         {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
316         {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
317         {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
318         {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}
319     }
320 };
321 
322 // P置换,32位 -> 32位
323 int P[] = { 16,  7, 20, 21,
324            29, 12, 28, 17,
325             1, 15, 23, 26,
326             5, 18, 31, 10,
327             2,  8, 24, 14,
328            32, 27,  3,  9,
329            19, 13, 30,  6,
330            22, 11,  4, 25 };
331 
332 /*DES算法实现*/
333 //密码函数f,接收32位数据和48位子密钥,产生一个32位的输出
334 bitset<32> f(bitset<32> R, bitset<48> k)
335 {
336     bitset<48> expandR;
337     // 扩展置换,32 -> 48
338     for (int i = 0; i < 48; ++i)
339         expandR[47 - i] = R[32 - E[i]];
340     // 异或
341     expandR = expandR ^ k;
342     // 查找S_BOX置换表
343     bitset<32> output;
344     int x = 0;
345     for (int i = 0; i < 48; i = i + 6)
346     {
347         int row = expandR[47 - i] * 2 + expandR[47 - i - 5];
348         int col = expandR[47 - i - 1] * 8 + expandR[47 - i - 2] * 4 + expandR[47 - i - 3] * 2 + expandR[47 - i - 4];
349         int num = S_BOX[i / 6][row][col];
350         bitset<4> binary(num);
351         output[31 - x] = binary[3];
352         output[31 - x - 1] = binary[2];
353         output[31 - x - 2] = binary[1];
354         output[31 - x - 3] = binary[0];
355         x += 4;
356     }
357     // P-置换,32 -> 32
358     bitset<32> tmp = output;
359     for (int i = 0; i < 32; ++i)
360         output[31 - i] = tmp[32 - P[i]];
361     return output;
362 }
363 
364 /**
365  *  对56位密钥的前后部分进行左移
366  */
367 bitset<28> leftShift(bitset<28> k, int shift)
368 {
369     bitset<28> tmp = k;
370     for (int i = 27; i >= 0; --i)
371     {
372         if (i - shift < 0)
373             k[i] = tmp[i - shift + 28];
374         else
375             k[i] = tmp[i - shift];
376     }
377     return k;
378 }
379 
380 /**
381  *  生成16个48位的子密钥
382  */
383 void generateKeys()
384 {
385     bitset<56> realKey;
386     bitset<28> left;
387     bitset<28> right;
388     bitset<48> compressKey;
389     // 去掉奇偶标记位,将64位密钥变成56位
390     for (int i = 0; i < 56; ++i)
391         realKey[55 - i] = key1[64 - PC_1[i]];
392     // 生成子密钥,保存在 subKeys[16] 中
393     for (int round = 0; round < 16; ++round)
394     {
395         // 前28位与后28位
396         for (int i = 28; i < 56; ++i)
397             left[i - 28] = realKey[i];
398         for (int i = 0; i < 28; ++i)
399             right[i] = realKey[i];
400         // 左移
401         left = leftShift(left, shiftBits[round]);
402         right = leftShift(right, shiftBits[round]);
403         // 压缩置换,由56位得到48位子密钥
404         for (int i = 28; i < 56; ++i)
405             realKey[i] = left[i - 28];
406         for (int i = 0; i < 28; ++i)
407             realKey[i] = right[i];
408         for (int i = 0; i < 48; ++i)
409             compressKey[47 - i] = realKey[56 - PC_2[i]];
410         subKey[round] = compressKey;
411     }
412 }
413 
414 /**
415  *  工具函数:将char字符数组转为二进制
416  */
417 bitset<64> charToBitset(const char s[8])
418 {
419     bitset<64> bits;
420     for (int i = 0; i < 8; ++i)
421         for (int j = 0; j < 8; ++j)
422             bits[i * 8 + j] = ((s[i] >> j) & 1);
423     return bits;
424 }
425 
426 /**
427  *  DES加密
428  */
429 bitset<64> encrypt(bitset<64>& plain)
430 {
431     bitset<64> cipher;
432     bitset<64> currentBits;
433     bitset<32> left;
434     bitset<32> right;
435     bitset<32> newLeft;
436     // 初始置换IP
437     for (int i = 0; i < 64; ++i)
438         currentBits[63 - i] = plain[64 - IP[i]];
439     // 获取 Li 和 Ri
440     for (int i = 32; i < 64; ++i)
441         left[i - 32] = currentBits[i];
442     for (int i = 0; i < 32; ++i)
443         right[i] = currentBits[i];
444     // 共16轮迭代
445     for (int round = 0; round < 16; ++round)
446     {
447         newLeft = right;
448         right = left ^ f(right, subKey[round]);
449         left = newLeft;
450     }
451     // 合并L16和R16,注意合并为 R16L16
452     for (int i = 0; i < 32; ++i)
453         cipher[i] = left[i];
454     for (int i = 32; i < 64; ++i)
455         cipher[i] = right[i - 32];
456     // 结尾置换IP-1
457     currentBits = cipher;
458     for (int i = 0; i < 64; ++i)
459         cipher[63 - i] = currentBits[64 - IP_1[i]];
460     // 返回密文
461     return cipher;
462 }
463 
464 /**
465  *  DES解密
466  */
467 bitset<64> decrypt(bitset<64>& cipher)
468 {
469     bitset<64> plain;
470     bitset<64> currentBits;
471     bitset<32> left;
472     bitset<32> right;
473     bitset<32> newLeft;
474     // 初始置换IP
475     for (int i = 0; i < 64; ++i)
476         currentBits[63 - i] = cipher[64 - IP[i]];
477     // 获取 Li 和 Ri
478     for (int i = 32; i < 64; ++i)
479         left[i - 32] = currentBits[i];
480     for (int i = 0; i < 32; ++i)
481         right[i] = currentBits[i];
482     // 共16轮迭代(子密钥逆序应用)
483     for (int round = 0; round < 16; ++round)
484     {
485         newLeft = right;
486         right = left ^ f(right, subKey[15 - round]);
487         left = newLeft;
488     }
489     // 合并L16和R16,注意合并为 R16L16
490     for (int i = 0; i < 32; ++i)
491         plain[i] = left[i];
492     for (int i = 32; i < 64; ++i)
493         plain[i] = right[i - 32];
494     // 结尾置换IP-1
495     currentBits = plain;
496     for (int i = 0; i < 64; ++i)
497         plain[63 - i] = currentBits[64 - IP_1[i]];
498     // 返回明文
499     return plain;
500 }
501 
502 int main(int argc, char const* argv[])
503 {
504     /*IDEA*/
505     idea idea;
506     byte key[16] = { 0x10, 0x1a, 0x0c, 0x0b, 0x01, 0x11, 0x09, 0x07, 0x32, 0xa1,
507         0xb3, 0x06, 0x23, 0x12, 0xd3, 0xf1 };
508     idea.setkey(key);
509     byte plaintext[8] = { 0xa7, 0x95, 0x87, 0x23, 0x1f, 0x2c, 0x6d, 0x73 };
510     idea.setplaintext(plaintext);
511     idea.enc();
512     idea.ideatest();
513 
514     /*DES*/
515     string s = "admin";
516     string k = "123456";
517     bitset<64> plain = charToBitset(s.c_str());
518     key1 = charToBitset(k.c_str());
519     // 生成16个子密钥
520     generateKeys();
521     // 密文写入 a.txt
522     bitset<64> cipher = encrypt(plain);
523     fstream file1;
524     file1.open("a.txt", ios::binary | ios::out);
525     file1.write((char*)&cipher, sizeof(cipher));
526     file1.close();
527 
528     // 读文件 a.txt
529     bitset<64> temp;
530     file1.open("a.txt", ios::binary | ios::in);
531     file1.read((char*)&temp, sizeof(temp));
532     file1.close();
533 
534     // 解密,并写入文件 b.txt
535     bitset<64> temp_plain = decrypt(temp);
536     file1.open("b.txt", ios::binary | ios::out);
537     file1.write((char*)&temp_plain, sizeof(temp_plain));
538     file1.close();
539 
540     return 0;
541 }

参考链接:

DES加密算法:https://www.cnblogs.com/songlee/p/5738096.html

IDEA加密算法:https://blog.csdn.net/weixin_46395886/article/details/114591075

(二)Java版本

①类图:

②效果图:

③目录结构:

④代码:

DES.java

 1 package arithmetic;
 2 
 3 import java.util.Scanner;
 4 
 5 import javax.crypto.Cipher;
 6 import javax.crypto.KeyGenerator;
 7 import javax.crypto.SecretKey;
 8 
 9 public class DES implements Method {
10     public void work(String str, String password) {
11         System.out.println("请输入要加密的明文:");
12         @SuppressWarnings("resource")
13         Scanner scanner= new Scanner(System.in);
14         String codeStringBegin=scanner.nextLine();
15         String codeStringEnd = null; // 加密后的密文
16         String decodeString = null; // 密文解密后得到的明文
17         
18         System.out.println("要加密的明文:" + codeStringBegin);
19         String cipherType = "DESede"; // 加密算法类型,可设置为DES、DESede、AES等字符串
20         try {
21             // 获取密钥生成器
22             KeyGenerator keyGen = KeyGenerator.getInstance(cipherType);
23             // 初始化密钥生成器,不同的加密算法其密钥长度可能不同
24             keyGen.init(112);
25             // 生成密钥
26             SecretKey key = keyGen.generateKey();
27 
28             // 得到密钥字节码
29             byte[] keyByte = key.getEncoded();
30             // 输出密钥的字节码
31             System.out.println("密钥是:");
32             for (int i = 0; i < keyByte.length; i++) {
33                 System.out.print(keyByte[i] + ",");
34             }
35             System.out.println("");
36             // 创建密码器
37             Cipher cp = Cipher.getInstance(cipherType);
38             // 初始化密码器
39             cp.init(Cipher.ENCRYPT_MODE, key);
40             System.out.println("要加密的字符串是:" + codeStringBegin);
41             byte[] codeStringByte = codeStringBegin.getBytes("UTF8");
42             System.out.println("要加密的字符串对应的字节码是:");
43             for (int i = 0; i < codeStringByte.length; i++) {
44                 System.out.print(codeStringByte[i] + ",");
45             }
46             System.out.println("");
47             // 开始加密
48             byte[] codeStringByteEnd = cp.doFinal(codeStringByte);
49             System.out.println("加密后的字符串对应的字节码是:");
50             for (int i = 0; i < codeStringByteEnd.length; i++) {
51                 System.out.print(codeStringByteEnd[i] + ",");
52             }
53             System.out.println("");
54             codeStringEnd = new String(codeStringByteEnd);
55             System.out.println("加密后的字符串是:" + codeStringEnd);
56             System.out.println("");
57             // 重新初始化密码器
58             cp.init(Cipher.DECRYPT_MODE, key);
59             // 开始解密
60             byte[] decodeStringByteEnd = cp.doFinal(codeStringByteEnd);
61             System.out.println("解密后的字符串对应的字节码是:");
62             for (int i = 0; i < decodeStringByteEnd.length; i++) {
63                 System.out.print(decodeStringByteEnd[i] + ",");
64             }
65             System.out.println("");
66             decodeString = new String(decodeStringByteEnd);
67             System.out.println("解密后的字符串是:" + decodeString);
68             System.out.println("");
69             System.out.println("--------------------------");
70         } catch (Exception e) {
71             e.printStackTrace();
72         }
73     }
74 
75     public static void main(String[] args) {
76         // TODO Auto-generated method stub
77         System.out.println("DES加密算法");
78         DES des = new DES();
79         try {
80             des.work("8787878787878787", "0E329232EA6D0D73");
81 
82         } catch (Exception e) {
83             System.out.println(e.getMessage());
84         }
85     }
86 
87 }

DESFactory.java

1 package arithmetic;
2 
3 public class DESFactory implements MethodFactory {
4     public DES produceMethod() {
5         System.out.println("使用DES算法");
6         return new DES();
7     }
8 }

IDEA.java

  1 package arithmetic;
  2 
  3 import javax.crypto.Cipher;
  4 import javax.crypto.KeyGenerator;
  5 import javax.crypto.SecretKey;
  6 import org.apache.commons.codec.binary.Base64;
  7 import org.bouncycastle.jce.provider.BouncyCastleProvider;
  8 
  9 import javax.crypto.spec.SecretKeySpec;
 10 import java.security.Key;
 11 import java.security.Security;
 12 import java.util.Scanner;
 13 
 14 public class IDEA implements Method {
 15 
 16     public static final String KEY_ALGORITHM = "IDEA";
 17 
 18     public static final String CIPHER_ALGORITHM = "IDEA/ECB/ISO10126Padding";
 19 
 20     public static byte[] initkey() throws Exception {
 21         // 加入bouncyCastle支持
 22         Security.addProvider(new BouncyCastleProvider());
 23         // 实例化密钥生成器
 24         KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
 25         // 初始化密钥生成器,IDEA要求密钥长度为128位
 26         kg.init(128);
 27         // 生成密钥
 28         SecretKey secretKey = kg.generateKey();
 29         // 获取二进制密钥编码形式
 30         return secretKey.getEncoded();
 31     }
 32 
 33     /**
 34      * 转换密钥
 35      * 
 36      * @param key 二进制密钥
 37      * @return Key 密钥
 38      */
 39     private static Key toKey(byte[] key) throws Exception {
 40         // 实例化DES密钥
 41         // 生成密钥
 42         SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
 43         return secretKey;
 44     }
 45 
 46     /**
 47      * 加密数据
 48      * 
 49      * @param data 待加密数据
 50      * @param key  密钥
 51      * @return byte[] 加密后的数据
 52      */
 53     private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
 54         // 加入bouncyCastle支持
 55         Security.addProvider(new BouncyCastleProvider());
 56         // 还原密钥
 57         Key k = toKey(key);
 58         // 实例化
 59         Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
 60         // 初始化,设置为加密模式
 61         cipher.init(Cipher.ENCRYPT_MODE, k);
 62         // 执行操作
 63         return cipher.doFinal(data);
 64     }
 65 
 66     /**
 67      * 解密数据
 68      * 
 69      * @param data 待解密数据
 70      * @param key  密钥
 71      * @return byte[] 解密后的数据
 72      */
 73     private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
 74         // 加入bouncyCastle支持
 75         Security.addProvider(new BouncyCastleProvider());
 76         // 还原密钥
 77         Key k = toKey(key);
 78         Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
 79         // 初始化,设置为解密模式
 80         cipher.init(Cipher.DECRYPT_MODE, k);
 81         // 执行操作
 82         return cipher.doFinal(data);
 83     }
 84 
 85     public static String getKey() {
 86         String result = null;
 87         try {
 88             result = Base64.encodeBase64String(initkey());
 89         } catch (Exception e) {
 90             e.printStackTrace();
 91         }
 92         return result;
 93     }
 94 
 95     public static String ideaEncrypt(String data, String key) {
 96         String result = null;
 97         try {
 98             byte[] data_en = encrypt(data.getBytes(), Base64.decodeBase64(key));
 99             result = Base64.encodeBase64String(data_en);
100         } catch (Exception e) {
101             e.printStackTrace();
102         }
103         return result;
104     }
105 
106     public static String ideaDecrypt(String data, String key) {
107         String result = null;
108         try {
109             byte[] data_de = decrypt(Base64.decodeBase64(data), Base64.decodeBase64(key));
110             ;
111             result = new String(data_de);
112         } catch (Exception e) {
113             e.printStackTrace();
114         }
115         return result;
116     }
117 
118     public void work(String str, String password) {
119         System.out.println("请输入要加密的明文:");
120         @SuppressWarnings("resource")
121         Scanner scanner= new Scanner(System.in);
122         String data=scanner.nextLine();
123         String key = getKey();
124         System.out.println("--------------------------");
125         System.out.println("要加密的原文:" + data);
126         System.out.println("密钥:" + key);
127         String data_en = ideaEncrypt(data, key);
128         System.out.println("密文:" + data_en);
129         String data_de = ideaDecrypt(data_en, key);
130         System.out.println("原文:" + data_de);
131         System.out.println("--------------------------");
132     }
133 
134     public static void main(String[] args) {
135         // TODO Auto-generated method stub
136         System.out.println("IDEA加密算法");
137         IDEA idea = new IDEA();
138         try {
139             idea.work("8787878787878787", "0E329232EA6D0D73");
140         } catch (Exception e) {
141             System.out.println(e.getMessage());
142         }
143     }
144 
145 }

IDEAFactory.java

1 package arithmetic;
2 
3 public class IDEAFactory implements MethodFactory {
4     public IDEA produceMethod() {
5         System.out.println("使用IDEA算法");
6         return new IDEA();
7     }
8 }

Main.java

 1 package arithmetic;
 2 
 3 import java.util.Scanner;
 4 
 5 public class Main {
 6     public static void main(String[] args) {
 7         DES des = new DES();
 8         IDEA idea = new IDEA();
 9         try {
10             int n = 0;
11             @SuppressWarnings("resource")
12             Scanner scanner = new Scanner(System.in);
13             while (n != 3) {
14                 /**
15                  * 主菜单
16                  */
17                 System.out.println("-----------------");
18                 System.out.println("请选择要使用的加密算法:");
19                 System.out.println("1.DES加密算法");
20                 System.out.println("2.IDEA加密算法");
21                 System.out.println("3.退出");
22                 System.out.println("请选择:");
23                 System.out.println("-----------------");
24                 /**
25                  * 判断输入的数据
26                  */
27                 if (scanner.hasNextInt()) {
28                     n = scanner.nextInt();
29                 } else {
30                     System.out.println("输入的不是整数,请重新输入:");
31                     continue;
32                 }
33                 switch (n) {
34                 case 1: {
35                     des.work("1787878787878787", "0E329232EA6D0D73");
36                     break;
37                 }
38                 case 2: {
39                     idea.work("8787878787878787", "0E329232EA6D0D73");
40                     break;
41                 }
42                 }
43             }
44         } catch (Exception e) {
45             System.out.println(e.getMessage());
46         }
47     }
48 }

Method.java

1 package arithmetic;
2 
3 public interface Method {
4     public abstract void work(String str, String password);
5 }

MethodFactory.java

1 package arithmetic;
2 
3 public interface MethodFactory {
4     public Method produceMethod();
5 }

参考链接:https://www.cnblogs.com/zyt-bg/p/9857820.html

原文地址:https://www.cnblogs.com/miao-com/p/15362394.html