DES加密解释见qq空间
http://user.qzone.qq.com/240011742/infocenter#!app=2&via=QZ.HashRefresh&pos=1365766516
这里只给出代码(STL版本):
1 //des.h
2 #pragma once
3 #include <bitset>
4 #include <iostream>
5
6 const int ip[] = {
7 58, 50, 42, 34, 26, 18, 10, 2,
8 60, 52, 44, 36, 28, 20, 12, 4,
9 62, 54, 46, 38, 30, 22, 14, 6,
10 64, 56, 48, 40, 32, 24, 16, 8,
11 57, 49, 41, 33, 25, 17, 9, 1,
12 59, 51, 43, 35, 27, 19, 11, 3,
13 61, 53, 45, 37, 29, 21, 13, 5,
14 63, 55, 47, 39, 31, 23, 15, 7
15 };
16
17 const int fp[] = {
18 40, 8, 48, 16, 56, 24, 64, 32,
19 39, 7, 47, 15, 55, 23, 63, 31,
20 38, 6, 46, 14, 54, 22, 62, 30,
21 37, 5, 45, 13, 53, 21, 61, 29,
22 36, 4, 44, 12, 52, 20, 60, 28,
23 35, 3, 43, 11, 51, 19, 59, 27,
24 34, 2, 42, 10, 50, 18, 58, 26,
25 33, 1, 41, 9, 49, 17, 57, 25
26 };
27
28 const int ei[] = {
29 32, 1, 2, 3, 4, 5,
30 4, 5, 6, 7, 8, 9,
31 8, 9, 10, 11, 12, 13,
32 12, 13, 14, 15, 16, 17,
33 16, 17, 18, 19, 20, 21,
34 20, 21, 22, 23, 24, 25,
35 24, 25, 26, 27, 28, 29,
36 28, 29, 30, 31, 32, 1
37 };
38
39 const int p32i[] = {
40 16, 7, 20, 21,
41 29, 12, 28, 17,
42 1, 15, 23, 26,
43 5, 18, 31, 10,
44 2, 8, 24, 14,
45 32, 27, 3, 9,
46 19, 13, 30, 6,
47 22, 11, 4, 25
48 };
49
50 const int sbox[8][64] = {
51 /* S1 */
52 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
53 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
54 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
55 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
56 /* S2 */
57 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
58 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
59 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
60 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
61 /* S3 */
62 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
63 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
64 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
65 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
66 /* S4 */
67 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
68 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
69 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
70 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
71 /* S5 */
72 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
73 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
74 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
75 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
76 /* S6 */
77 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
78 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
79 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
80 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
81 /* S7 */
82 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
83 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
84 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
85 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
86 /* S8 */
87 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
88 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
89 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
90 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
91 };
92
93 const int pc1[] = {
94 57, 49, 41, 33, 25, 17, 9,
95 1, 58, 50, 42, 34, 26, 18,
96 10, 2, 59, 51, 43, 35, 27,
97 19, 11, 3, 60, 52, 44, 36,
98 63, 55, 47, 39, 31, 23, 15,
99 7, 62, 54, 46, 38, 30, 22,
100 14, 6, 61, 53, 45, 37, 29,
101 21, 13, 5, 28, 20, 12, 4
102 };
103
104 const int pc2[] = {
105 14, 17, 11, 24, 1, 5,
106 3, 28, 15, 6, 21, 10,
107 23, 19, 12, 4, 26, 8,
108 16, 7, 27, 20, 13, 2,
109 41, 52, 31, 37, 47, 55,
110 30, 40, 51, 45, 33, 48,
111 44, 49, 39, 56, 34, 53,
112 46, 42, 50, 36, 29, 32
113 };
114
115
116 /* number left rotations of pc1 */
117 const int totrot[] = {
118 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
119 };
120
121 //循环左移
122 inline void circleLeftMove(std::bitset<28> &bit28)
123 {
124 int temp = bit28[27];
125 bit28 <<= 1;
126 bit28 |= temp;
127 }
128
129 //初始置换
130 inline void initialExchange(std::bitset<64> &bit64, std::bitset<32> &L, std::bitset<32> &R)
131 {
132 for (int i = 0; i < 64; i++)
133 {
134 if (i >= 32)
135 R.set(63 - i, bit64[64 - ip[i]]);
136 else
137 L.set(31 - i, bit64[64 - ip[i]]);
138 }
139 }
140
141 //逆初始置换
142 inline void uninitialExchange(std::bitset<64> &bit64, std::bitset<32> &L, std::bitset<32> &R)
143 {
144 for (int i = 0; i < 64; i++)
145 {
146 int index = fp[i];
147 if (index > 32)
148 bit64.set(63 - i, L[64 - fp[i]]);
149 //R.set(63 - i, bit64[63 - ip[i]]);
150 else
151 bit64.set(63 - i, R[32 - fp[i]]);
152 //L.set(31 - i, bit64[63 - ip[i]]);
153 }
154 }
155
156 //扩充置换
157 inline std::bitset<48> expandExchange(std::bitset<32> &bit32)
158 {
159 std::bitset<48> retBit48(0);
160 for (int i = 0; i < 48; i++)
161 retBit48.set(47 - i, bit32[32 - ei[i]]);
162 return retBit48;
163 }
164
165 //置换选择1
166 inline void exchangeChoose(std::bitset<64> &bit64, std::bitset<28> &C, std::bitset<28> &D)
167 {
168 for (int i = 0; i < 56; i++)
169 {
170 if (i >= 28)
171 D.set(55 - i, bit64[64 - pc1[i]]);
172 else
173 C.set(27 - i, bit64[64 - pc1[i]]);
174 }
175 }
176
177 //置换选择2
178 inline std::bitset<48> exchangeChoose(std::bitset<28> &C, std::bitset<28> &D)
179 {
180 std::bitset<48> retBit48(0);
181 int index;
182 for (int i = 0; i < 48; i++)
183 {
184 index = pc2[i];
185 if (index > 28)
186 retBit48.set(47 - i, D[56 - index]);
187 else
188 retBit48.set(47 - i, C[28 - index]);
189 }
190 return retBit48;
191 }
192
193 //代换选择(S盒)
194 inline std::bitset<32> replaceChoose(std::bitset<48> &bit48)
195 {
196 std::bitset<32> retBit32(0);
197 std::bitset<6> temp(0);
198 int row, col;
199 for (int i = 0; i < 8; i++)
200 {
201 for (int j = 0; j < 6; j++)
202 temp.set(j, bit48[(7 - i) * 6 + j]);
203 row = temp[5] * 2 + temp[0];
204 temp <<= 1;
205 temp >>= 2;
206 col = (int)temp.to_ulong();
207 retBit32 <<= 4;
208 retBit32 |= sbox[i][row * 16 + col];
209 }
210 return retBit32;
211 }
212
213 //置换
214 inline std::bitset<32> exchange(std::bitset<32> &bit32)
215 {
216 std::bitset<32> retBit32(0);
217 for (int i = 0; i < 32; i++)
218 retBit32.set(31 - i, bit32[32 - p32i[i]]);
219 return retBit32;
220 }
221
222 //一次迭代
223 inline void onceIteration(std::bitset<32> &L, std::bitset<32> &R, std::bitset<28> &C, std::bitset<28> &D, int index)
224 {
225 for (int i = 0; i < totrot[index]; i++)
226 {
227 circleLeftMove(C);
228 circleLeftMove(D);
229 }
230 L ^= exchange(replaceChoose(expandExchange(R) ^ exchangeChoose(C, D)));
231 std::bitset<32> temp = R;
232
233 R = L;
234 L = temp;
235 }
236
237 inline void encypher(std::bitset<64> &text, std::bitset<64> &cipherKey)
238 {
239 std::bitset<28> C = 0, D = 0;
240 std::bitset<32> L = 0, R = 0;
241 exchangeChoose(cipherKey, C, D);
242 initialExchange(text, L, R);
243 for (int i = 0; i < 16; i++)
244 onceIteration(L, R, C, D, i);
245 uninitialExchange(text, L, R);
246 }
1 //main.cpp
2 #include <iostream>
3 #include "des.h"
4 #include <cstring>
5 using namespace std;
6
7 int main(int argc, char **argv)
8 {
9 char cipherKeyStr[65];
10 char textStr[65];
11 cout << "please input the cipher key:";
12 cin >> cipherKeyStr;
13 cout << "please input the plaintext:";
14 cin >> textStr;
15 bitset<64> cipherKey(cipherKeyStr);
16 bitset<64> text(textStr);
17 encypher(text, cipherKey);
18 cout << text << endl;
19 }
可以用http://hi.baidu.com/barrypp/item/d7983d19b9e02d426826bbe7里的数据来测试。注意把16进制数转换成2进制数
另外注意一下C++中inline的使用,如果你用了inline,你想运行修改后的代码,必须要把整个工程重新编译生成代码才能成功。好吧,到今天才发现这个问题,真的是太水了,各路大神勿喷==
原文链接: https://www.cnblogs.com/MichaelChong/archive/2013/04/12/3017228.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/84339
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!