一个Delphi写的DES算法, 翻译成C#
其实.NET Framework已经提供实现DES算法的类: System.Security.Cryptography.DESCryptoServiceProvider。之所以要把一个Delphi写的DES算法翻译成C#,是因为网友espnstar想用Delphi加密,C#解密,详见CSDN贴子: http://topic.csdn.net/t/20050726/18/4169690.html。
1
// Des.cs - 一个Delphi写的DES算法, 翻译成C#
2
// Wed 2005.09.14
3
4
// public byte[] EncryBytes (byte[] inData, byte[] keyByte);
5
// public byte[] DecryBytes (byte[] inData, byte[] keyByte);
6
// public string EncryStr (string Str, string Key );
7
// public string DecryStr (string Str, string Key );
8
// public string EncryStrHex(string Str, string Key );
9
// public string DecryStrHex(string StrHex, string Key );
10
11
namespace Skyiv
12
{
13
using System;
14
using System.Text;
15
16
enum TDesMode { dmEncry, dmDecry };
17
18
class Des
19
{
20
static readonly byte [] BitIP =
21
{
22
57, 49, 41, 33, 25, 17, 9, 1,
23
59, 51, 43, 35, 27, 19, 11, 3,
24
61, 53, 45, 37, 29, 21, 13, 5,
25
63, 55, 47, 39, 31, 23, 15, 7,
26
56, 48, 40, 32, 24, 16, 8, 0,
27
58, 50, 42, 34, 26, 18, 10, 2,
28
60, 52, 44, 36, 28, 20, 12, 4,
29
62, 54, 46, 38, 30, 22, 14, 6
30
};
31
32
static readonly byte [] BitCP =
33
{
34
39, 7, 47, 15, 55, 23, 63, 31,
35
38, 6, 46, 14, 54, 22, 62, 30,
36
37, 5, 45, 13, 53, 21, 61, 29,
37
36, 4, 44, 12, 52, 20, 60, 28,
38
35, 3, 43, 11, 51, 19, 59, 27,
39
34, 2, 42, 10, 50, 18, 58, 26,
40
33, 1, 41, 9, 49, 17, 57, 25,
41
32, 0, 40, 8, 48, 16, 56, 24
42
};
43
44
static readonly int [] BitExp =
45
{
46
31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
47
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
48
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0
49
};
50
51
static readonly byte [] BitPM =
52
{
53
15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
54
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24
55
};
56
57
static readonly byte [,] sBox =
58
{
59
{
60
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
61
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
62
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
63
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
64
},
65
{
66
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
67
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
68
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
69
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
70
},
71
{
72
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
73
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
74
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
75
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
76
},
77
{
78
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
79
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
80
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
81
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
82
},
83
{
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
},
89
{
90
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
91
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
92
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
93
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
94
},
95
{
96
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
97
13, 0, 11, 7, 4, 9, 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
},
101
{
102
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
103
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
104
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
105
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
106
}
107
};
108
109
static readonly byte [] BitPMC1 =
110
{
111
56, 48, 40, 32, 24, 16, 8,
112
0, 57, 49, 41, 33, 25, 17,
113
9, 1, 58, 50, 42, 34, 26,
114
18, 10, 2, 59, 51, 43, 35,
115
62, 54, 46, 38, 30, 22, 14,
116
6, 61, 53, 45, 37, 29, 21,
117
13, 5, 60, 52, 44, 36, 28,
118
20, 12, 4, 27, 19, 11, 3
119
};
120
121
static readonly byte [] BitPMC2 =
122
{
123
13, 16, 10, 23, 0, 4,
124
2, 27, 14, 5, 20, 9,
125
22, 18, 11, 3, 25, 7,
126
15, 6, 26, 19, 12, 1,
127
40, 51, 30, 36, 46, 54,
128
29, 39, 50, 44, 32, 47,
129
43, 48, 38, 55, 33, 52,
130
45, 41, 49, 35, 28, 31
131
};
132
133
byte [][] SubKey;
134
135
public Des()
136
{
137
SubKey = new byte [16][];
138
for (int i = 0; i < SubKey.Length; i++)
139
{
140
SubKey[i] = new byte [6];
141
}
142
}
143
144
void initPermutation(byte [] inData)
145
{
146
byte [] newData = new byte [8];
147
for (int i = 0; i < 64; i++)
148
{
149
if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)
150
{
151
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
152
}
153
}
154
Array.Copy(newData, inData, 8);
155
}
156
157
void conversePermutation(byte [] inData)
158
{
159
byte [] newData = new byte [8];
160
for (int i = 0; i < 64; i++)
161
{
162
if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)
163
{
164
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
165
}
166
}
167
Array.Copy(newData, inData, 8);
168
}
169
170
void expand(byte [] inData, byte [] outData)
171
{
172
Array.Clear(outData, 0, 6);
173
for (int i = 0; i < 48; i++)
174
{
175
if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)
176
{
177
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
178
}
179
}
180
}
181
182
void permutation(byte [] inData)
183
{
184
byte [] newData = new byte [4];
185
for (int i = 0; i < 32; i++)
186
{
187
if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)
188
{
189
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
190
}
191
}
192
Array.Copy(newData, inData, 4);
193
}
194
195
byte si(byte s, byte inByte)
196
{
197
int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);
198
return (byte)(sBox[s,c] & 0x0f);
199
}
200
201
void permutationChoose1(byte [] inData, byte [] outData)
202
{
203
Array.Clear(outData, 0, 7);
204
for (int i = 0; i < 56; i++)
205
{
206
if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
207
{
208
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
209
}
210
}
211
}
212
213
void permutationChoose2(byte [] inData, byte [] outData)
214
{
215
Array.Clear(outData, 0, 6);
216
for (int i = 0; i < 48; i++)
217
{
218
if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
219
{
220
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
221
}
222
}
223
}
224
225
void cycleMove(byte [] inData, byte bitMove)
226
{
227
for (int i = 0; i < bitMove; i++)
228
{
229
inData[0] = (byte)((inData[0] << 1) | (inData[1] >> 7));
230
inData[1] = (byte)((inData[1] << 1) | (inData[2] >> 7));
231
inData[2] = (byte)((inData[2] << 1) | (inData[3] >> 7));
232
inData[3] = (byte)((inData[3] << 1) | ((inData[0] & 0x10) >> 4));
233
inData[0] = (byte)(inData[0] & 0x0f);
234
}
235
}
236
237
static readonly byte [] bitDisplace = { 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 };
238
239
void makeKey(byte [] inKey, byte [][] outKey)
240
{
241
byte [] outData56 = new byte [7];
242
byte [] key28l = new byte [4];
243
byte [] key28r = new byte [4];
244
byte [] key56o = new byte [7];
245
246
permutationChoose1(inKey, outData56);
247
key28l[0] = (byte)(outData56[0] >> 4);
248
key28l[1] = (byte)((outData56[0] << 4) | (outData56[1] >> 4));
249
key28l[2] = (byte)((outData56[1] << 4) | (outData56[2] >> 4));
250
key28l[3] = (byte)((outData56[2] << 4) | (outData56[3] >> 4));
251
key28r[0] = (byte)(outData56[3] & 0x0f);
252
key28r[1] = (byte)(outData56[4]);
253
key28r[2] = (byte)(outData56[5]);
254
key28r[3] = (byte)(outData56[6]);
255
256
for (int i = 0; i < 16; i++)
257
{
258
cycleMove(key28l, bitDisplace[i]);
259
cycleMove(key28r, bitDisplace[i]);
260
key56o[0] = (byte)((key28l[0] << 4) | (key28l[1] >> 4));
261
key56o[1] = (byte)((key28l[1] << 4) | (key28l[2] >> 4));
262
key56o[2] = (byte)((key28l[2] << 4) | (key28l[3] >> 4));
263
key56o[3] = (byte)((key28l[3] << 4) | (key28r[0]));
264
key56o[4] = (byte)(key28r[1]);
265
key56o[5] = (byte)(key28r[2]);
266
key56o[6] = (byte)(key28r[3]);
267
permutationChoose2(key56o, outKey[i]);
268
};
269
}
270
271
void encry(byte [] inData, byte [] subKey, byte [] outData)
272
{
273
byte [] outBuf = new byte [6];
274
byte [] buf = new byte [8];
275
276
expand(inData, outBuf);
277
for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);
278
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
279
buf[0] = (byte)(outBuf[0] >> 2); //xxxxxx -> 2
280
buf[1] = (byte)(((outBuf[0] & 0x03) << 4) | (outBuf[1] >> 4)); // 4 <- xx xxxx -> 4
281
buf[2] = (byte)(((outBuf[1] & 0x0f) << 2) | (outBuf[2] >> 6)); // 2 <- xxxx xx -> 6
282
buf[3] = (byte)(outBuf[2] & 0x3f); // xxxxxx
283
buf[4] = (byte)(outBuf[3] >> 2); // xxxxxx
284
buf[5] = (byte)(((outBuf[3] & 0x03) << 4) | (outBuf[4] >> 4)); // xx xxxx
285
buf[6] = (byte)(((outBuf[4] & 0x0f) << 2) | (outBuf[5] >> 6)); // xxxx xx
286
buf[7] = (byte)(outBuf[5] & 0x3f); // xxxxxx
287
for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);
288
for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i*2] << 4) | buf[i*2+1]);
289
permutation(outBuf);
290
for (int i = 0; i < 4; i++) outData[i] = outBuf[i];
291
}
292
293
// inData, outData 都为 8 Bytes,否则出错
294
void desData(TDesMode desMode, byte [] inData, byte [] outData)
295
{
296
int i, j;
297
byte [] temp = new byte [4];
298
byte [] buf = new byte [4];
299
300
for (i = 0; i < 8; i++) outData[i] = inData[i];
301
initPermutation(outData);
302
if (desMode == TDesMode.dmEncry)
303
{
304
for (i = 0; i < 16; i++)
305
{
306
for (j = 0; j < 4; j++) temp[j] = outData[j]; //temp = Ln
307
for (j = 0; j < 4; j++) outData[j] = outData[j+4]; //Ln+1 = Rn
308
encry(outData, SubKey[i], buf); //Rn ==Kn==> buf
309
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]); //Rn+1 = Ln^buf
310
};
311
for (j = 0; j < 4; j++) temp[j] = outData[j+4];
312
for (j = 0; j < 4; j++) outData[j+4] = outData[j];
313
for (j = 0; j < 4; j++) outData[j] = temp[j];
314
}
315
else if (desMode == TDesMode.dmDecry)
316
{
317
for (i = 15; i >= 0; i--)
318
{
319
for (j = 0; j < 4; j++) temp[j] = outData[j];
320
for (j = 0; j < 4; j++) outData[j] = outData[j+4];
321
encry(outData, SubKey[i], buf);
322
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]);
323
};
324
for (j = 0; j < 4; j++) temp[j] = outData[j+4];
325
for (j = 0; j < 4; j++) outData[j+4] = outData[j];
326
for (j = 0; j < 4; j++) outData[j] = temp[j];
327
};
328
conversePermutation(outData);
329
}
330
331
byte [] Redim(byte [] arr, int newSize)
332
{
333
if (newSize == arr.Length) return arr;
334
byte [] newArr = new byte [newSize];
335
Array.Copy(arr, 0, newArr, 0, Math.Min(arr.Length, newSize));
336
return newArr;
337
}
338
339
//////////////////////////////////////////////////////////////
340
341
public byte [] EncryBytes(byte [] inData, byte [] keyByte)
342
{
343
byte [] tmpByte = new byte [8];
344
byte [] outByte = new byte [8];
345
346
if ((inData.Length > 0) && (inData[inData.Length-1] == 0))
347
{
348
throw new ArgumentException("The last byte is 0.", "inData");
349
}
350
if (inData.Length % 8 != 0) inData = Redim(inData, (inData.Length+7)/8*8);
351
if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
352
makeKey(keyByte, SubKey);
353
354
byte [] outData = new byte [inData.Length];
355
for (int i = 0; i < inData.Length / 8; i++)
356
{
357
for (int j = 0; j < 8; j++)
358
{
359
tmpByte[j] = inData[i * 8 + j];
360
}
361
desData(TDesMode.dmEncry, tmpByte, outByte);
362
for (int j = 0; j < 8; j++)
363
{
364
outData[i * 8 + j] = outByte[j];
365
}
366
};
367
368
return outData;
369
}
370
371
public byte [] DecryBytes(byte [] inData, byte [] keyByte)
372
{
373
byte [] tmpByte = new byte [8];
374
byte [] outByte = new byte [8];
375
376
if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);
377
makeKey(keyByte, SubKey);
378
379
byte [] outData = new byte [(inData.Length+7)/8*8];
380
for (int i = 0; i < inData.Length / 8; i++)
381
{
382
for (int j = 0; j < 8; j++)
383
{
384
tmpByte[j] = inData[i * 8 + j];
385
}
386
desData(TDesMode.dmDecry, tmpByte, outByte);
387
for (int j = 0; j < 8; j++)
388
{
389
outData[i * 8 + j] = outByte[j];
390
}
391
};
392
393
int n = outData.Length - 1;
394
while (n >= 0 && outData[n] == 0) --n;
395
return Redim(outData, n+1);
396
}
397
398
public string EncryStr(string Str, string Key)
399
{
400
byte [] inData = Encoding.UTF8.GetBytes(Str);
401
byte [] keyByte = Encoding.UTF8.GetBytes(Key);
402
byte [] tmpByte = EncryBytes(inData, keyByte);
403
StringBuilder tmpStr = new StringBuilder();
404
foreach (byte b in tmpByte)
405
{
406
tmpStr.Append((char)b);
407
}
408
return tmpStr.ToString();
409
}
410
411
public string DecryStr(string Str, string Key)
412
{
413
byte [] inData = new byte [Str.Length];
414
for (int i = 0; i < Str.Length; i++)
415
{
416
inData[i] = (byte)Str[i];
417
}
418
byte [] keyByte = Encoding.UTF8.GetBytes(Key);
419
byte [] tmpByte = DecryBytes(inData, keyByte);
420
return Encoding.UTF8.GetString(tmpByte);
421
}
422
423
public string EncryStrHex(string Str, string Key)
424
{
425
byte [] inData = Encoding.UTF8.GetBytes(Str);
426
byte [] keyByte = Encoding.UTF8.GetBytes(Key);
427
byte [] tmpByte = EncryBytes(inData, keyByte);
428
StringBuilder tmpStr = new StringBuilder();
429
foreach (byte b in tmpByte)
430
{
431
tmpStr.AppendFormat("{0:X2}", b);
432
}
433
return tmpStr.ToString();
434
}
435
436
public string DecryStrHex(string StrHex, string Key)
437
{
438
if (StrHex.Length % 2 != 0)
439
{
440
throw new ArgumentException("String length must be even.", "StrHex");
441
}
442
byte [] inData = new byte [StrHex.Length / 2];
443
for (int i = 0; i < StrHex.Length; i += 2)
444
{
445
inData[i/2] = (byte)(Uri.FromHex(StrHex[i])*16 + Uri.FromHex(StrHex[i+1]));
446
}
447
byte [] keyByte = Encoding.UTF8.GetBytes(Key);
448
byte [] tmpByte = DecryBytes(inData, keyByte);
449
return Encoding.UTF8.GetString(tmpByte);
450
}
451
} // End of class Des
452
} // End of namespace Skyiv
感谢网友espnstar提供Delphi版的源程序:
// Des.cs - 一个Delphi写的DES算法, 翻译成C#2
// Wed 2005.09.143

4
// public byte[] EncryBytes (byte[] inData, byte[] keyByte);5
// public byte[] DecryBytes (byte[] inData, byte[] keyByte);6
// public string EncryStr (string Str, string Key );7
// public string DecryStr (string Str, string Key );8
// public string EncryStrHex(string Str, string Key );9
// public string DecryStrHex(string StrHex, string Key );10

11
namespace Skyiv12
{13
using System;14
using System.Text;15

16
enum TDesMode { dmEncry, dmDecry };17

18
class Des19
{20
static readonly byte [] BitIP =21
{22
57, 49, 41, 33, 25, 17, 9, 1,23
59, 51, 43, 35, 27, 19, 11, 3,24
61, 53, 45, 37, 29, 21, 13, 5,25
63, 55, 47, 39, 31, 23, 15, 7,26
56, 48, 40, 32, 24, 16, 8, 0,27
58, 50, 42, 34, 26, 18, 10, 2,28
60, 52, 44, 36, 28, 20, 12, 4,29
62, 54, 46, 38, 30, 22, 14, 630
};31

32
static readonly byte [] BitCP =33
{34
39, 7, 47, 15, 55, 23, 63, 31,35
38, 6, 46, 14, 54, 22, 62, 30,36
37, 5, 45, 13, 53, 21, 61, 29,37
36, 4, 44, 12, 52, 20, 60, 28,38
35, 3, 43, 11, 51, 19, 59, 27,39
34, 2, 42, 10, 50, 18, 58, 26,40
33, 1, 41, 9, 49, 17, 57, 25,41
32, 0, 40, 8, 48, 16, 56, 2442
};43

44
static readonly int [] BitExp =45
{46
31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,47
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,48
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 049
};50

51
static readonly byte [] BitPM =52
{53
15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,54
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,2455
};56

57
static readonly byte [,] sBox =58
{59
{60
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,61
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,62
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,63
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 1364
},65
{66
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,67
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,68
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,69
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 970
},71
{72
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,73
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,74
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,75
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 1276
},77
{78
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,79
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,80
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,81
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 1482
},83
{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, 388
},89
{90
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,91
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,92
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,93
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 1394
},95
{96
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,97
13, 0, 11, 7, 4, 9, 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, 12100
},101
{102
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,103
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,104
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,105
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11106
}107
};108

109
static readonly byte [] BitPMC1 =110
{111
56, 48, 40, 32, 24, 16, 8,112
0, 57, 49, 41, 33, 25, 17,113
9, 1, 58, 50, 42, 34, 26,114
18, 10, 2, 59, 51, 43, 35,115
62, 54, 46, 38, 30, 22, 14,116
6, 61, 53, 45, 37, 29, 21,117
13, 5, 60, 52, 44, 36, 28,118
20, 12, 4, 27, 19, 11, 3119
};120

121
static readonly byte [] BitPMC2 =122
{123
13, 16, 10, 23, 0, 4,124
2, 27, 14, 5, 20, 9,125
22, 18, 11, 3, 25, 7,126
15, 6, 26, 19, 12, 1,127
40, 51, 30, 36, 46, 54,128
29, 39, 50, 44, 32, 47,129
43, 48, 38, 55, 33, 52,130
45, 41, 49, 35, 28, 31131
};132

133
byte [][] SubKey;134

135
public Des()136
{137
SubKey = new byte [16][];138
for (int i = 0; i < SubKey.Length; i++)139
{140
SubKey[i] = new byte [6];141
}142
}143

144
void initPermutation(byte [] inData)145
{146
byte [] newData = new byte [8];147
for (int i = 0; i < 64; i++)148
{149
if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)150
{151
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));152
}153
}154
Array.Copy(newData, inData, 8);155
}156

157
void conversePermutation(byte [] inData)158
{159
byte [] newData = new byte [8];160
for (int i = 0; i < 64; i++)161
{162
if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)163
{164
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));165
}166
}167
Array.Copy(newData, inData, 8);168
}169

170
void expand(byte [] inData, byte [] outData)171
{172
Array.Clear(outData, 0, 6);173
for (int i = 0; i < 48; i++)174
{175
if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)176
{177
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));178
}179
}180
}181

182
void permutation(byte [] inData)183
{184
byte [] newData = new byte [4];185
for (int i = 0; i < 32; i++)186
{187
if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)188
{189
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));190
}191
}192
Array.Copy(newData, inData, 4);193
}194

195
byte si(byte s, byte inByte)196
{197
int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);198
return (byte)(sBox[s,c] & 0x0f);199
}200

201
void permutationChoose1(byte [] inData, byte [] outData)202
{203
Array.Clear(outData, 0, 7);204
for (int i = 0; i < 56; i++)205
{206
if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)207
{208
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));209
}210
}211
}212

213
void permutationChoose2(byte [] inData, byte [] outData)214
{215
Array.Clear(outData, 0, 6);216
for (int i = 0; i < 48; i++)217
{218
if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)219
{220
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));221
}222
}223
}224

225
void cycleMove(byte [] inData, byte bitMove)226
{227
for (int i = 0; i < bitMove; i++)228
{229
inData[0] = (byte)((inData[0] << 1) | (inData[1] >> 7));230
inData[1] = (byte)((inData[1] << 1) | (inData[2] >> 7));231
inData[2] = (byte)((inData[2] << 1) | (inData[3] >> 7));232
inData[3] = (byte)((inData[3] << 1) | ((inData[0] & 0x10) >> 4));233
inData[0] = (byte)(inData[0] & 0x0f);234
}235
}236

237
static readonly byte [] bitDisplace = { 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 };238

239
void makeKey(byte [] inKey, byte [][] outKey)240
{241
byte [] outData56 = new byte [7];242
byte [] key28l = new byte [4];243
byte [] key28r = new byte [4];244
byte [] key56o = new byte [7];245

246
permutationChoose1(inKey, outData56);247
key28l[0] = (byte)(outData56[0] >> 4);248
key28l[1] = (byte)((outData56[0] << 4) | (outData56[1] >> 4));249
key28l[2] = (byte)((outData56[1] << 4) | (outData56[2] >> 4));250
key28l[3] = (byte)((outData56[2] << 4) | (outData56[3] >> 4));251
key28r[0] = (byte)(outData56[3] & 0x0f);252
key28r[1] = (byte)(outData56[4]);253
key28r[2] = (byte)(outData56[5]);254
key28r[3] = (byte)(outData56[6]);255

256
for (int i = 0; i < 16; i++)257
{258
cycleMove(key28l, bitDisplace[i]);259
cycleMove(key28r, bitDisplace[i]);260
key56o[0] = (byte)((key28l[0] << 4) | (key28l[1] >> 4));261
key56o[1] = (byte)((key28l[1] << 4) | (key28l[2] >> 4));262
key56o[2] = (byte)((key28l[2] << 4) | (key28l[3] >> 4));263
key56o[3] = (byte)((key28l[3] << 4) | (key28r[0]));264
key56o[4] = (byte)(key28r[1]);265
key56o[5] = (byte)(key28r[2]);266
key56o[6] = (byte)(key28r[3]);267
permutationChoose2(key56o, outKey[i]);268
};269
}270

271
void encry(byte [] inData, byte [] subKey, byte [] outData)272
{273
byte [] outBuf = new byte [6];274
byte [] buf = new byte [8];275

276
expand(inData, outBuf);277
for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);278
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx279
buf[0] = (byte)(outBuf[0] >> 2); //xxxxxx -> 2280
buf[1] = (byte)(((outBuf[0] & 0x03) << 4) | (outBuf[1] >> 4)); // 4 <- xx xxxx -> 4281
buf[2] = (byte)(((outBuf[1] & 0x0f) << 2) | (outBuf[2] >> 6)); // 2 <- xxxx xx -> 6282
buf[3] = (byte)(outBuf[2] & 0x3f); // xxxxxx283
buf[4] = (byte)(outBuf[3] >> 2); // xxxxxx284
buf[5] = (byte)(((outBuf[3] & 0x03) << 4) | (outBuf[4] >> 4)); // xx xxxx285
buf[6] = (byte)(((outBuf[4] & 0x0f) << 2) | (outBuf[5] >> 6)); // xxxx xx286
buf[7] = (byte)(outBuf[5] & 0x3f); // xxxxxx287
for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);288
for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i*2] << 4) | buf[i*2+1]);289
permutation(outBuf);290
for (int i = 0; i < 4; i++) outData[i] = outBuf[i];291
}292

293
// inData, outData 都为 8 Bytes,否则出错294
void desData(TDesMode desMode, byte [] inData, byte [] outData)295
{296
int i, j;297
byte [] temp = new byte [4];298
byte [] buf = new byte [4];299

300
for (i = 0; i < 8; i++) outData[i] = inData[i];301
initPermutation(outData);302
if (desMode == TDesMode.dmEncry)303
{304
for (i = 0; i < 16; i++)305
{306
for (j = 0; j < 4; j++) temp[j] = outData[j]; //temp = Ln307
for (j = 0; j < 4; j++) outData[j] = outData[j+4]; //Ln+1 = Rn308
encry(outData, SubKey[i], buf); //Rn ==Kn==> buf309
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]); //Rn+1 = Ln^buf310
};311
for (j = 0; j < 4; j++) temp[j] = outData[j+4];312
for (j = 0; j < 4; j++) outData[j+4] = outData[j];313
for (j = 0; j < 4; j++) outData[j] = temp[j];314
}315
else if (desMode == TDesMode.dmDecry)316
{317
for (i = 15; i >= 0; i--)318
{319
for (j = 0; j < 4; j++) temp[j] = outData[j];320
for (j = 0; j < 4; j++) outData[j] = outData[j+4];321
encry(outData, SubKey[i], buf);322
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]);323
};324
for (j = 0; j < 4; j++) temp[j] = outData[j+4];325
for (j = 0; j < 4; j++) outData[j+4] = outData[j];326
for (j = 0; j < 4; j++) outData[j] = temp[j];327
};328
conversePermutation(outData);329
}330

331
byte [] Redim(byte [] arr, int newSize)332
{333
if (newSize == arr.Length) return arr;334
byte [] newArr = new byte [newSize];335
Array.Copy(arr, 0, newArr, 0, Math.Min(arr.Length, newSize));336
return newArr;337
}338

339
//////////////////////////////////////////////////////////////340

341
public byte [] EncryBytes(byte [] inData, byte [] keyByte)342
{343
byte [] tmpByte = new byte [8];344
byte [] outByte = new byte [8];345

346
if ((inData.Length > 0) && (inData[inData.Length-1] == 0))347
{348
throw new ArgumentException("The last byte is 0.", "inData");349
}350
if (inData.Length % 8 != 0) inData = Redim(inData, (inData.Length+7)/8*8);351
if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);352
makeKey(keyByte, SubKey);353

354
byte [] outData = new byte [inData.Length];355
for (int i = 0; i < inData.Length / 8; i++)356
{357
for (int j = 0; j < 8; j++)358
{359
tmpByte[j] = inData[i * 8 + j];360
}361
desData(TDesMode.dmEncry, tmpByte, outByte);362
for (int j = 0; j < 8; j++)363
{364
outData[i * 8 + j] = outByte[j];365
}366
};367

368
return outData;369
}370

371
public byte [] DecryBytes(byte [] inData, byte [] keyByte)372
{373
byte [] tmpByte = new byte [8];374
byte [] outByte = new byte [8];375

376
if (keyByte.Length != 8) keyByte = Redim(keyByte, 8);377
makeKey(keyByte, SubKey);378

379
byte [] outData = new byte [(inData.Length+7)/8*8];380
for (int i = 0; i < inData.Length / 8; i++)381
{382
for (int j = 0; j < 8; j++)383
{384
tmpByte[j] = inData[i * 8 + j];385
}386
desData(TDesMode.dmDecry, tmpByte, outByte);387
for (int j = 0; j < 8; j++)388
{389
outData[i * 8 + j] = outByte[j];390
}391
};392

393
int n = outData.Length - 1;394
while (n >= 0 && outData[n] == 0) --n;395
return Redim(outData, n+1);396
}397

398
public string EncryStr(string Str, string Key)399
{400
byte [] inData = Encoding.UTF8.GetBytes(Str);401
byte [] keyByte = Encoding.UTF8.GetBytes(Key);402
byte [] tmpByte = EncryBytes(inData, keyByte);403
StringBuilder tmpStr = new StringBuilder();404
foreach (byte b in tmpByte)405
{406
tmpStr.Append((char)b);407
}408
return tmpStr.ToString();409
}410

411
public string DecryStr(string Str, string Key)412
{413
byte [] inData = new byte [Str.Length];414
for (int i = 0; i < Str.Length; i++)415
{416
inData[i] = (byte)Str[i];417
}418
byte [] keyByte = Encoding.UTF8.GetBytes(Key);419
byte [] tmpByte = DecryBytes(inData, keyByte);420
return Encoding.UTF8.GetString(tmpByte);421
}422

423
public string EncryStrHex(string Str, string Key)424
{425
byte [] inData = Encoding.UTF8.GetBytes(Str);426
byte [] keyByte = Encoding.UTF8.GetBytes(Key);427
byte [] tmpByte = EncryBytes(inData, keyByte);428
StringBuilder tmpStr = new StringBuilder();429
foreach (byte b in tmpByte)430
{431
tmpStr.AppendFormat("{0:X2}", b);432
}433
return tmpStr.ToString();434
}435

436
public string DecryStrHex(string StrHex, string Key)437
{438
if (StrHex.Length % 2 != 0)439
{440
throw new ArgumentException("String length must be even.", "StrHex");441
}442
byte [] inData = new byte [StrHex.Length / 2];443
for (int i = 0; i < StrHex.Length; i += 2)444
{445
inData[i/2] = (byte)(Uri.FromHex(StrHex[i])*16 + Uri.FromHex(StrHex[i+1]));446
}447
byte [] keyByte = Encoding.UTF8.GetBytes(Key);448
byte [] tmpByte = DecryBytes(inData, keyByte);449
return Encoding.UTF8.GetString(tmpByte);450
}451
} // End of class Des452
} // End of namespace Skyiv 1
unit Des;
2
3
interface
4
5
uses SysUtils;
6
7
type
8
TKeyByte = array[0..5] of Byte;
9
TDesMode = (dmEncry, dmDecry);
10
11
function EncryStr(Str, Key: String): String;
12
function DecryStr(Str, Key: String): String;
13
function EncryStrHex(Str, Key: String): String;
14
function DecryStrHex(StrHex, Key: String): String;
15
16
const
17
BitIP: array[0..63] of Byte =
18
(57, 49, 41, 33, 25, 17, 9, 1,
19
59, 51, 43, 35, 27, 19, 11, 3,
20
61, 53, 45, 37, 29, 21, 13, 5,
21
63, 55, 47, 39, 31, 23, 15, 7,
22
56, 48, 40, 32, 24, 16, 8, 0,
23
58, 50, 42, 34, 26, 18, 10, 2,
24
60, 52, 44, 36, 28, 20, 12, 4,
25
62, 54, 46, 38, 30, 22, 14, 6 );
26
27
BitCP: array[0..63] of Byte =
28
( 39, 7, 47, 15, 55, 23, 63, 31,
29
38, 6, 46, 14, 54, 22, 62, 30,
30
37, 5, 45, 13, 53, 21, 61, 29,
31
36, 4, 44, 12, 52, 20, 60, 28,
32
35, 3, 43, 11, 51, 19, 59, 27,
33
34, 2, 42, 10, 50, 18, 58, 26,
34
33, 1, 41, 9, 49, 17, 57, 25,
35
32, 0, 40, 8, 48, 16, 56, 24 );
36
37
BitExp: array[0..47] of Integer =
38
( 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
39
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
40
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31,0 );
41
42
BitPM: array[0..31] of Byte =
43
( 15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
44
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24 );
45
46
sBox: array[0..7] of array[0..63] of Byte =
47
( ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
48
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
49
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
50
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 ),
51
52
( 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
53
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
54
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
55
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 ),
56
57
( 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
58
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
59
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
60
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ),
61
62
( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
63
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
64
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
65
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 ),
66
67
( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
68
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
69
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
70
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 ),
71
72
( 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
73
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
74
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
75
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 ),
76
77
( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
78
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
79
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
80
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 ),
81
82
( 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
83
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
84
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
85
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ) );
86
87
BitPMC1: array[0..55] of Byte =
88
( 56, 48, 40, 32, 24, 16, 8,
89
0, 57, 49, 41, 33, 25, 17,
90
9, 1, 58, 50, 42, 34, 26,
91
18, 10, 2, 59, 51, 43, 35,
92
62, 54, 46, 38, 30, 22, 14,
93
6, 61, 53, 45, 37, 29, 21,
94
13, 5, 60, 52, 44, 36, 28,
95
20, 12, 4, 27, 19, 11, 3 );
96
97
BitPMC2: array[0..47] of Byte =
98
( 13, 16, 10, 23, 0, 4,
99
2, 27, 14, 5, 20, 9,
100
22, 18, 11, 3, 25, 7,
101
15, 6, 26, 19, 12, 1,
102
40, 51, 30, 36, 46, 54,
103
29, 39, 50, 44, 32, 47,
104
43, 48, 38, 55, 33, 52,
105
45, 41, 49, 35, 28, 31 );
106
107
var
108
subKey: array[0..15] of TKeyByte;
109
110
implementation
111
112
procedure initPermutation(var inData: array of Byte);
113
var
114
newData: array[0..7] of Byte;
115
i: Integer;
116
begin
117
FillChar(newData, 8, 0);
118
for i := 0 to 63 do
119
if (inData[BitIP[i] shr 3] and (1 shl (7- (BitIP[i] and $07)))) <> 0 then
120
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
121
for i := 0 to 7 do inData[i] := newData[i];
122
end;
123
124
procedure conversePermutation(var inData: array of Byte);
125
var
126
newData: array[0..7] of Byte;
127
i: Integer;
128
begin
129
FillChar(newData, 8, 0);
130
for i := 0 to 63 do
131
if (inData[BitCP[i] shr 3] and (1 shl (7-(BitCP[i] and $07)))) <> 0 then
132
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
133
for i := 0 to 7 do inData[i] := newData[i];
134
end;
135
136
procedure expand(inData: array of Byte; var outData: array of Byte);
137
var
138
i: Integer;
139
begin
140
FillChar(outData, 6, 0);
141
for i := 0 to 47 do
142
if (inData[BitExp[i] shr 3] and (1 shl (7-(BitExp[i] and $07)))) <> 0 then
143
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));
144
end;
145
146
procedure permutation(var inData: array of Byte);
147
var
148
newData: array[0..3] of Byte;
149
i: Integer;
150
begin
151
FillChar(newData, 4, 0);
152
for i := 0 to 31 do
153
if (inData[BitPM[i] shr 3] and (1 shl (7-(BitPM[i] and $07)))) <> 0 then
154
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
155
for i := 0 to 3 do inData[i] := newData[i];
156
end;
157
158
function si(s,inByte: Byte): Byte;
159
var
160
c: Byte;
161
begin
162
c := (inByte and $20) or ((inByte and $1e) shr 1) or
163
((inByte and $01) shl 4);
164
Result := (sBox[s][c] and $0f);
165
end;
166
167
procedure permutationChoose1(inData: array of Byte;
168
var outData: array of Byte);
169
var
170
i: Integer;
171
begin
172
FillChar(outData, 7, 0);
173
for i := 0 to 55 do
174
if (inData[BitPMC1[i] shr 3] and (1 shl (7-(BitPMC1[i] and $07)))) <> 0 then
175
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));
176
end;
177
178
179
180
181
procedure permutationChoose2(inData: array of Byte;
182
var outData: array of Byte);
183
var
184
i: Integer;
185
begin
186
FillChar(outData, 6, 0);
187
for i := 0 to 47 do
188
if (inData[BitPMC2[i] shr 3] and (1 shl (7-(BitPMC2[i] and $07)))) <> 0 then
189
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));
190
end;
191
192
procedure cycleMove(var inData: array of Byte; bitMove: Byte);
193
var
194
i: Integer;
195
begin
196
for i := 0 to bitMove - 1 do
197
begin
198
inData[0] := (inData[0] shl 1) or (inData[1] shr 7);
199
inData[1] := (inData[1] shl 1) or (inData[2] shr 7);
200
inData[2] := (inData[2] shl 1) or (inData[3] shr 7);
201
inData[3] := (inData[3] shl 1) or ((inData[0] and $10) shr 4);
202
inData[0] := (inData[0] and $0f);
203
end;
204
end;
205
206
procedure makeKey(inKey: array of Byte; var outKey: array of TKeyByte);
207
const
208
bitDisplace: array[0..15] of Byte =
209
( 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 );
210
var
211
outData56: array[0..6] of Byte;
212
key28l: array[0..3] of Byte;
213
key28r: array[0..3] of Byte;
214
key56o: array[0..6] of Byte;
215
i: Integer;
216
begin
217
permutationChoose1(inKey, outData56);
218
219
key28l[0] := outData56[0] shr 4;
220
key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4);
221
key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4);
222
key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4);
223
key28r[0] := outData56[3] and $0f;
224
key28r[1] := outData56[4];
225
key28r[2] := outData56[5];
226
key28r[3] := outData56[6];
227
228
for i := 0 to 15 do
229
begin
230
cycleMove(key28l, bitDisplace[i]);
231
cycleMove(key28r, bitDisplace[i]);
232
key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4);
233
key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4);
234
key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4);
235
key56o[3] := (key28l[3] shl 4) or (key28r[0]);
236
key56o[4] := key28r[1];
237
key56o[5] := key28r[2];
238
key56o[6] := key28r[3];
239
permutationChoose2(key56o, outKey[i]);
240
end;
241
end;
242
243
procedure encry(inData, subKey: array of Byte;
244
var outData: array of Byte);
245
var
246
outBuf: array[0..5] of Byte;
247
buf: array[0..7] of Byte;
248
i: Integer;
249
begin
250
expand(inData, outBuf);
251
for i := 0 to 5 do outBuf[i] := outBuf[i] xor subKey[i];
252
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
253
buf[0] := outBuf[0] shr 2; //xxxxxx -> 2
254
buf[1] := ((outBuf[0] and $03) shl 4) or (outBuf[1] shr 4); // 4 <- xx xxxx -> 4
255
buf[2] := ((outBuf[1] and $0f) shl 2) or (outBuf[2] shr 6); // 2 <- xxxx xx -> 6
256
buf[3] := outBuf[2] and $3f; // xxxxxx
257
buf[4] := outBuf[3] shr 2; // xxxxxx
258
buf[5] := ((outBuf[3] and $03) shl 4) or (outBuf[4] shr 4); // xx xxxx
259
buf[6] := ((outBuf[4] and $0f) shl 2) or (outBuf[5] shr 6); // xxxx xx
260
buf[7] := outBuf[5] and $3f; // xxxxxx
261
for i := 0 to 7 do buf[i] := si(i, buf[i]);
262
for i := 0 to 3 do outBuf[i] := (buf[i*2] shl 4) or buf[i*2+1];
263
permutation(outBuf);
264
for i := 0 to 3 do outData[i] := outBuf[i];
265
end;
266
267
procedure desData(desMode: TDesMode;
268
inData: array of Byte; var outData: array of Byte);
269
// inData, outData 都为8Bytes,否则出错
270
var
271
i, j: Integer;
272
temp, buf: array[0..3] of Byte;
273
begin
274
for i := 0 to 7 do outData[i] := inData[i];
275
initPermutation(outData);
276
if desMode = dmEncry then
277
begin
278
for i := 0 to 15 do
279
begin
280
for j := 0 to 3 do temp[j] := outData[j]; //temp = Ln
281
for j := 0 to 3 do outData[j] := outData[j + 4]; //Ln+1 = Rn
282
encry(outData, subKey[i], buf); //Rn ==Kn==> buf
283
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j]; //Rn+1 = Ln^buf
284
end;
285
286
for j := 0 to 3 do temp[j] := outData[j + 4];
287
for j := 0 to 3 do outData[j + 4] := outData[j];
288
for j := 0 to 3 do outData[j] := temp[j];
289
end
290
else if desMode = dmDecry then
291
begin
292
for i := 15 downto 0 do
293
begin
294
for j := 0 to 3 do temp[j] := outData[j];
295
for j := 0 to 3 do outData[j] := outData[j + 4];
296
encry(outData, subKey[i], buf);
297
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];
298
end;
299
for j := 0 to 3 do temp[j] := outData[j + 4];
300
for j := 0 to 3 do outData[j + 4] := outData[j];
301
for j := 0 to 3 do outData[j] := temp[j];
302
end;
303
conversePermutation(outData);
304
end;
305
306
//////////////////////////////////////////////////////////////
307
308
function EncryStr(Str, Key: String): String;
309
var
310
StrByte, OutByte, KeyByte: array[0..7] of Byte;
311
StrResult: String;
312
I, J: Integer;
313
begin
314
if (Length(Str) > 0) and (Ord(Str[Length(Str)]) = 0) then
315
raise Exception.Create('Error: the last char is NULL char.');
316
if Length(Key) < 8 then
317
while Length(Key) < 8 do Key := Key + Chr(0);
318
while Length(Str) mod 8 <> 0 do Str := Str + Chr(0);
319
320
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
321
makeKey(keyByte, subKey);
322
323
StrResult := '';
324
325
for I := 0 to Length(Str) div 8 - 1 do
326
begin
327
for J := 0 to 7 do
328
StrByte[J] := Ord(Str[I * 8 + J + 1]);
329
desData(dmEncry, StrByte, OutByte);
330
for J := 0 to 7 do
331
StrResult := StrResult + Chr(OutByte[J]);
332
end;
333
334
Result := StrResult;
335
end;
336
337
function DecryStr(Str, Key: String): String;
338
var
339
StrByte, OutByte, KeyByte: array[0..7] of Byte;
340
StrResult: String;
341
I, J: Integer;
342
begin
343
if Length(Key) < 8 then
344
while Length(Key) < 8 do Key := Key + Chr(0);
345
346
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
347
makeKey(keyByte, subKey);
348
349
StrResult := '';
350
351
for I := 0 to Length(Str) div 8 - 1 do
352
begin
353
for J := 0 to 7 do StrByte[J] := Ord(Str[I * 8 + J + 1]);
354
desData(dmDecry, StrByte, OutByte);
355
for J := 0 to 7 do
356
StrResult := StrResult + Chr(OutByte[J]);
357
end;
358
while (Length(StrResult) > 0) and
359
(Ord(StrResult[Length(StrResult)]) = 0) do
360
Delete(StrResult, Length(StrResult), 1);
361
Result := StrResult;
362
end;
363
364
///////////////////////////////////////////////////////////
365
366
function EncryStrHex(Str, Key: String): String;
367
var
368
StrResult, TempResult, Temp: String;
369
I: Integer;
370
begin
371
TempResult := EncryStr(Str, Key);
372
StrResult := '';
373
for I := 0 to Length(TempResult) - 1 do
374
begin
375
Temp := Format('%x', [Ord(TempResult[I + 1])]);
376
if Length(Temp) = 1 then Temp := '0' + Temp;
377
StrResult := StrResult + Temp;
378
end;
379
Result := StrResult;
380
end;
381
382
function DecryStrHex(StrHex, Key: String): String;
383
function HexToInt(Hex: String): Integer;
384
var
385
I, Res: Integer;
386
ch: Char;
387
begin
388
Res := 0;
389
for I := 0 to Length(Hex) - 1 do
390
begin
391
ch := Hex[I + 1];
392
if (ch >= '0') and (ch <= '9') then
393
Res := Res * 16 + Ord(ch) - Ord('0')
394
else if (ch >= 'A') and (ch <= 'F') then
395
Res := Res * 16 + Ord(ch) - Ord('A') + 10
396
else if (ch >= 'a') and (ch <= 'f') then
397
Res := Res * 16 + Ord(ch) - Ord('a') + 10
398
else raise Exception.Create('Error: not a Hex String');
399
end;
400
Result := Res;
401
end;
402
403
var
404
Str, Temp: String;
405
I: Integer;
406
begin
407
Str := '';
408
for I := 0 to Length(StrHex) div 2 - 1 do
409
begin
410
Temp := Copy(StrHex, I * 2 + 1, 2);
411
Str := Str + Chr(HexToInt(Temp));
412
end;
413
Result := DecryStr(Str, Key);
414
end;
415
416
end.
unit Des;2

3
interface4

5
uses SysUtils;6

7
type8
TKeyByte = array[0..5] of Byte;9
TDesMode = (dmEncry, dmDecry);10

11
function EncryStr(Str, Key: String): String;12
function DecryStr(Str, Key: String): String;13
function EncryStrHex(Str, Key: String): String;14
function DecryStrHex(StrHex, Key: String): String;15

16
const17
BitIP: array[0..63] of Byte =18
(57, 49, 41, 33, 25, 17, 9, 1,19
59, 51, 43, 35, 27, 19, 11, 3,20
61, 53, 45, 37, 29, 21, 13, 5,21
63, 55, 47, 39, 31, 23, 15, 7,22
56, 48, 40, 32, 24, 16, 8, 0,23
58, 50, 42, 34, 26, 18, 10, 2,24
60, 52, 44, 36, 28, 20, 12, 4,25
62, 54, 46, 38, 30, 22, 14, 6 );26

27
BitCP: array[0..63] of Byte =28
( 39, 7, 47, 15, 55, 23, 63, 31,29
38, 6, 46, 14, 54, 22, 62, 30,30
37, 5, 45, 13, 53, 21, 61, 29,31
36, 4, 44, 12, 52, 20, 60, 28,32
35, 3, 43, 11, 51, 19, 59, 27,33
34, 2, 42, 10, 50, 18, 58, 26,34
33, 1, 41, 9, 49, 17, 57, 25,35
32, 0, 40, 8, 48, 16, 56, 24 );36

37
BitExp: array[0..47] of Integer =38
( 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,39
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,40
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31,0 );41

42
BitPM: array[0..31] of Byte =43
( 15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,44
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24 );45

46
sBox: array[0..7] of array[0..63] of Byte =47
( ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,48
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,49
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,50
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 ),51

52
( 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,53
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,54
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,55
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 ),56

57
( 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,58
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,59
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,60
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ),61

62
( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,63
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,64
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,65
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 ),66

67
( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,68
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,69
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,70
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 ),71

72
( 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,73
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,74
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,75
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 ),76

77
( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,78
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,79
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,80
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 ),81

82
( 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,83
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,84
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,85
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ) );86

87
BitPMC1: array[0..55] of Byte =88
( 56, 48, 40, 32, 24, 16, 8,89
0, 57, 49, 41, 33, 25, 17,90
9, 1, 58, 50, 42, 34, 26,91
18, 10, 2, 59, 51, 43, 35,92
62, 54, 46, 38, 30, 22, 14,93
6, 61, 53, 45, 37, 29, 21,94
13, 5, 60, 52, 44, 36, 28,95
20, 12, 4, 27, 19, 11, 3 );96

97
BitPMC2: array[0..47] of Byte =98
( 13, 16, 10, 23, 0, 4,99
2, 27, 14, 5, 20, 9,100
22, 18, 11, 3, 25, 7,101
15, 6, 26, 19, 12, 1,102
40, 51, 30, 36, 46, 54,103
29, 39, 50, 44, 32, 47,104
43, 48, 38, 55, 33, 52,105
45, 41, 49, 35, 28, 31 );106

107
var108
subKey: array[0..15] of TKeyByte;109

110
implementation111

112
procedure initPermutation(var inData: array of Byte);113
var114
newData: array[0..7] of Byte;115
i: Integer;116
begin117
FillChar(newData, 8, 0);118
for i := 0 to 63 do119
if (inData[BitIP[i] shr 3] and (1 shl (7- (BitIP[i] and $07)))) <> 0 then120
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));121
for i := 0 to 7 do inData[i] := newData[i];122
end;123

124
procedure conversePermutation(var inData: array of Byte);125
var126
newData: array[0..7] of Byte;127
i: Integer;128
begin129
FillChar(newData, 8, 0);130
for i := 0 to 63 do131
if (inData[BitCP[i] shr 3] and (1 shl (7-(BitCP[i] and $07)))) <> 0 then132
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));133
for i := 0 to 7 do inData[i] := newData[i];134
end;135

136
procedure expand(inData: array of Byte; var outData: array of Byte);137
var138
i: Integer;139
begin140
FillChar(outData, 6, 0);141
for i := 0 to 47 do142
if (inData[BitExp[i] shr 3] and (1 shl (7-(BitExp[i] and $07)))) <> 0 then143
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));144
end;145

146
procedure permutation(var inData: array of Byte);147
var148
newData: array[0..3] of Byte;149
i: Integer;150
begin151
FillChar(newData, 4, 0);152
for i := 0 to 31 do153
if (inData[BitPM[i] shr 3] and (1 shl (7-(BitPM[i] and $07)))) <> 0 then154
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));155
for i := 0 to 3 do inData[i] := newData[i];156
end;157

158
function si(s,inByte: Byte): Byte;159
var160
c: Byte;161
begin162
c := (inByte and $20) or ((inByte and $1e) shr 1) or163
((inByte and $01) shl 4);164
Result := (sBox[s][c] and $0f);165
end;166

167
procedure permutationChoose1(inData: array of Byte;168
var outData: array of Byte);169
var170
i: Integer;171
begin172
FillChar(outData, 7, 0);173
for i := 0 to 55 do174
if (inData[BitPMC1[i] shr 3] and (1 shl (7-(BitPMC1[i] and $07)))) <> 0 then175
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));176
end;177

178

179

180

181
procedure permutationChoose2(inData: array of Byte;182
var outData: array of Byte);183
var184
i: Integer;185
begin186
FillChar(outData, 6, 0);187
for i := 0 to 47 do188
if (inData[BitPMC2[i] shr 3] and (1 shl (7-(BitPMC2[i] and $07)))) <> 0 then189
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));190
end;191

192
procedure cycleMove(var inData: array of Byte; bitMove: Byte);193
var194
i: Integer;195
begin196
for i := 0 to bitMove - 1 do197
begin198
inData[0] := (inData[0] shl 1) or (inData[1] shr 7);199
inData[1] := (inData[1] shl 1) or (inData[2] shr 7);200
inData[2] := (inData[2] shl 1) or (inData[3] shr 7);201
inData[3] := (inData[3] shl 1) or ((inData[0] and $10) shr 4);202
inData[0] := (inData[0] and $0f);203
end;204
end;205

206
procedure makeKey(inKey: array of Byte; var outKey: array of TKeyByte);207
const208
bitDisplace: array[0..15] of Byte =209
( 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 );210
var211
outData56: array[0..6] of Byte;212
key28l: array[0..3] of Byte;213
key28r: array[0..3] of Byte;214
key56o: array[0..6] of Byte;215
i: Integer;216
begin217
permutationChoose1(inKey, outData56);218

219
key28l[0] := outData56[0] shr 4;220
key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4);221
key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4);222
key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4);223
key28r[0] := outData56[3] and $0f;224
key28r[1] := outData56[4];225
key28r[2] := outData56[5];226
key28r[3] := outData56[6];227

228
for i := 0 to 15 do229
begin230
cycleMove(key28l, bitDisplace[i]);231
cycleMove(key28r, bitDisplace[i]);232
key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4);233
key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4);234
key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4);235
key56o[3] := (key28l[3] shl 4) or (key28r[0]);236
key56o[4] := key28r[1];237
key56o[5] := key28r[2];238
key56o[6] := key28r[3];239
permutationChoose2(key56o, outKey[i]);240
end;241
end;242

243
procedure encry(inData, subKey: array of Byte;244
var outData: array of Byte);245
var246
outBuf: array[0..5] of Byte;247
buf: array[0..7] of Byte;248
i: Integer;249
begin250
expand(inData, outBuf);251
for i := 0 to 5 do outBuf[i] := outBuf[i] xor subKey[i];252
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx253
buf[0] := outBuf[0] shr 2; //xxxxxx -> 2254
buf[1] := ((outBuf[0] and $03) shl 4) or (outBuf[1] shr 4); // 4 <- xx xxxx -> 4255
buf[2] := ((outBuf[1] and $0f) shl 2) or (outBuf[2] shr 6); // 2 <- xxxx xx -> 6256
buf[3] := outBuf[2] and $3f; // xxxxxx257
buf[4] := outBuf[3] shr 2; // xxxxxx258
buf[5] := ((outBuf[3] and $03) shl 4) or (outBuf[4] shr 4); // xx xxxx259
buf[6] := ((outBuf[4] and $0f) shl 2) or (outBuf[5] shr 6); // xxxx xx260
buf[7] := outBuf[5] and $3f; // xxxxxx261
for i := 0 to 7 do buf[i] := si(i, buf[i]);262
for i := 0 to 3 do outBuf[i] := (buf[i*2] shl 4) or buf[i*2+1];263
permutation(outBuf);264
for i := 0 to 3 do outData[i] := outBuf[i];265
end;266

267
procedure desData(desMode: TDesMode;268
inData: array of Byte; var outData: array of Byte);269
// inData, outData 都为8Bytes,否则出错270
var271
i, j: Integer;272
temp, buf: array[0..3] of Byte;273
begin274
for i := 0 to 7 do outData[i] := inData[i];275
initPermutation(outData);276
if desMode = dmEncry then277
begin278
for i := 0 to 15 do279
begin280
for j := 0 to 3 do temp[j] := outData[j]; //temp = Ln281
for j := 0 to 3 do outData[j] := outData[j + 4]; //Ln+1 = Rn282
encry(outData, subKey[i], buf); //Rn ==Kn==> buf283
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j]; //Rn+1 = Ln^buf284
end;285

286
for j := 0 to 3 do temp[j] := outData[j + 4];287
for j := 0 to 3 do outData[j + 4] := outData[j];288
for j := 0 to 3 do outData[j] := temp[j];289
end290
else if desMode = dmDecry then291
begin292
for i := 15 downto 0 do293
begin294
for j := 0 to 3 do temp[j] := outData[j];295
for j := 0 to 3 do outData[j] := outData[j + 4];296
encry(outData, subKey[i], buf);297
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];298
end;299
for j := 0 to 3 do temp[j] := outData[j + 4];300
for j := 0 to 3 do outData[j + 4] := outData[j];301
for j := 0 to 3 do outData[j] := temp[j];302
end;303
conversePermutation(outData);304
end;305

306
//////////////////////////////////////////////////////////////307

308
function EncryStr(Str, Key: String): String;309
var310
StrByte, OutByte, KeyByte: array[0..7] of Byte;311
StrResult: String;312
I, J: Integer;313
begin314
if (Length(Str) > 0) and (Ord(Str[Length(Str)]) = 0) then315
raise Exception.Create('Error: the last char is NULL char.');316
if Length(Key) < 8 then317
while Length(Key) < 8 do Key := Key + Chr(0);318
while Length(Str) mod 8 <> 0 do Str := Str + Chr(0);319

320
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);321
makeKey(keyByte, subKey);322

323
StrResult := '';324

325
for I := 0 to Length(Str) div 8 - 1 do326
begin327
for J := 0 to 7 do328
StrByte[J] := Ord(Str[I * 8 + J + 1]);329
desData(dmEncry, StrByte, OutByte);330
for J := 0 to 7 do331
StrResult := StrResult + Chr(OutByte[J]);332
end;333

334
Result := StrResult;335
end;336

337
function DecryStr(Str, Key: String): String;338
var339
StrByte, OutByte, KeyByte: array[0..7] of Byte;340
StrResult: String;341
I, J: Integer;342
begin343
if Length(Key) < 8 then344
while Length(Key) < 8 do Key := Key + Chr(0);345

346
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);347
makeKey(keyByte, subKey);348

349
StrResult := '';350

351
for I := 0 to Length(Str) div 8 - 1 do352
begin353
for J := 0 to 7 do StrByte[J] := Ord(Str[I * 8 + J + 1]);354
desData(dmDecry, StrByte, OutByte);355
for J := 0 to 7 do356
StrResult := StrResult + Chr(OutByte[J]);357
end;358
while (Length(StrResult) > 0) and359
(Ord(StrResult[Length(StrResult)]) = 0) do360
Delete(StrResult, Length(StrResult), 1);361
Result := StrResult;362
end;363

364
///////////////////////////////////////////////////////////365

366
function EncryStrHex(Str, Key: String): String;367
var368
StrResult, TempResult, Temp: String;369
I: Integer;370
begin371
TempResult := EncryStr(Str, Key);372
StrResult := '';373
for I := 0 to Length(TempResult) - 1 do374
begin375
Temp := Format('%x', [Ord(TempResult[I + 1])]);376
if Length(Temp) = 1 then Temp := '0' + Temp;377
StrResult := StrResult + Temp;378
end;379
Result := StrResult;380
end;381

382
function DecryStrHex(StrHex, Key: String): String;383
function HexToInt(Hex: String): Integer;384
var385
I, Res: Integer;386
ch: Char;387
begin388
Res := 0;389
for I := 0 to Length(Hex) - 1 do390
begin391
ch := Hex[I + 1];392
if (ch >= '0') and (ch <= '9') then393
Res := Res * 16 + Ord(ch) - Ord('0')394
else if (ch >= 'A') and (ch <= 'F') then395
Res := Res * 16 + Ord(ch) - Ord('A') + 10396
else if (ch >= 'a') and (ch <= 'f') then397
Res := Res * 16 + Ord(ch) - Ord('a') + 10398
else raise Exception.Create('Error: not a Hex String');399
end;400
Result := Res;401
end;402

403
var404
Str, Temp: String;405
I: Integer;406
begin407
Str := '';408
for I := 0 to Length(StrHex) div 2 - 1 do409
begin410
Temp := Copy(StrHex, I * 2 + 1, 2);411
Str := Str + Chr(HexToInt(Temp));412
end;413
Result := DecryStr(Str, Key);414
end;415

416
end.


浙公网安备 33010602011771号