1
//以下为MD5算法用c#的实现
2
//MD5.cs
3
//MD5 16-bit,32-bits algorithm implemented in C#
4
5
using System;
6
using System.Text;
7
namespace Encrypter
8
{
9
/**//// <summary>
10
/// Summary description for MD5.
11
/// </summary>
12
public class MD5
13
{
14
const int BITS_TO_A_BYTE = 8;
15
const int BYTES_TO_A_WORD = 4;
16
const int BITS_TO_A_WORD = 32;
17
private static long[] m_lOnBits = new long[30 + 1];
18
private static long[] m_l2Power = new long[30 + 1];
19
20
private static long LShift(long lValue, long iShiftBits)
21
{
22
long LShift = 0;
23
if (iShiftBits == 0)
24
{
25
LShift = lValue;
26
return LShift;
27
}
28
else
29
{
30
if( iShiftBits == 31)
31
{
32
if (Convert.ToBoolean(lValue & 1))
33
{
34
LShift = 0x80000000;
35
}
36
else
37
{
38
LShift = 0;
39
}
40
return LShift;
41
}
42
else
43
{
44
if( iShiftBits < 0 || iShiftBits > 31)
45
{
46
// Err.Raise 6;
47
}
48
}
49
}
50
51
if (Convert.ToBoolean((lValue & m_l2Power[31 - iShiftBits])))
52
{
53
LShift = ((lValue & m_lOnBits[31 - (iShiftBits + 1)]) * m_l2Power[iShiftBits]) | 0x80000000;
54
}
55
else
56
{
57
LShift = ((lValue & m_lOnBits[31 - iShiftBits]) * m_l2Power[iShiftBits]);
58
}
59
60
return LShift;
61
}
62
63
private static long RShift(long lValue, long iShiftBits)
64
{
65
long RShift = 0;
66
if (iShiftBits == 0)
67
{
68
RShift = lValue;
69
return RShift;
70
}
71
else
72
{
73
if( iShiftBits == 31)
74
{
75
if (Convert.ToBoolean(lValue & 0x80000000))
76
{
77
RShift = 1;
78
}
79
else
80
{
81
RShift = 0;
82
}
83
return RShift;
84
}
85
else
86
{
87
if( iShiftBits < 0 || iShiftBits > 31)
88
{
89
// Err.Raise 6;
90
}
91
}
92
}
93
94
RShift = (lValue & 0x7FFFFFFE) / m_l2Power[iShiftBits];
95
96
if (Convert.ToBoolean((lValue & 0x80000000)))
97
{
98
RShift = (RShift | (0x40000000 / m_l2Power[iShiftBits - 1]));
99
}
100
101
return RShift;
102
}
103
104
private static long RotateLeft(long lValue, long iShiftBits)
105
{
106
long RotateLeft = 0;
107
RotateLeft = LShift(lValue, iShiftBits) | RShift(lValue, (32 - iShiftBits));
108
return RotateLeft;
109
}
110
111
private static long AddUnsigned(long lX, long lY)
112
{
113
long AddUnsigned = 0;
114
long lX4 = 0;
115
long lY4 = 0;
116
long lX8 = 0;
117
long lY8 = 0;
118
long lResult = 0;
119
120
lX8 = lX & 0x80000000;
121
lY8 = lY & 0x80000000;
122
lX4 = lX & 0x40000000;
123
lY4 = lY & 0x40000000;
124
125
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
126
if (Convert.ToBoolean(lX4 & lY4))
127
{
128
lResult = lResult ^ 0x80000000 ^ lX8 ^ lY8;
129
}
130
else if( Convert.ToBoolean(lX4 | lY4))
131
{
132
if (Convert.ToBoolean(lResult & 0x40000000))
133
{
134
lResult = lResult ^ 0xC0000000 ^ lX8 ^ lY8;
135
}
136
else
137
{
138
lResult = lResult ^ 0x40000000 ^ lX8 ^ lY8;
139
}
140
}
141
else
142
{
143
lResult = lResult ^ lX8 ^ lY8;
144
}
145
AddUnsigned = lResult;
146
return AddUnsigned;
147
}
148
149
private static long md5_F(long x, long y, long z)
150
{
151
long md5_F = 0;
152
md5_F = (x & y) | (( ~x) & z);
153
return md5_F;
154
}
155
156
private static long md5_G(long x, long y, long z)
157
{
158
long md5_G = 0;
159
md5_G = (x & z) | (y & ( ~z));
160
return md5_G;
161
}
162
163
private static long md5_H(long x, long y, long z)
164
{
165
long md5_H = 0;
166
md5_H = (x ^ y ^ z);
167
return md5_H;
168
}
169
170
private static long md5_I(long x, long y, long z)
171
{
172
long md5_I = 0;
173
md5_I = (y ^ (x | (~z)));
174
return md5_I;
175
}
176
177
private static void md5_FF(ref long a, long b, long c, long d, long x, long s, long ac)
178
{
179
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_F(b, c, d), x), ac));
180
a = RotateLeft(a, s);
181
a = AddUnsigned(a, b);
182
}
183
184
private static void md5_GG(ref long a, long b, long c, long d, long x, long s, long ac)
185
{
186
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_G(b, c, d), x), ac));
187
a = RotateLeft(a, s);
188
a = AddUnsigned(a, b);
189
}
190
191
private static void md5_HH(ref long a, long b, long c, long d, long x, long s, long ac)
192
{
193
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_H(b, c, d), x), ac));
194
a = RotateLeft(a, s);
195
a = AddUnsigned(a, b);
196
}
197
198
private static void md5_II(ref long a, long b, long c, long d, long x, long s, long ac)
199
{
200
a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_I(b, c, d), x), ac));
201
a = RotateLeft(a, s);
202
a = AddUnsigned(a, b);
203
}
204
205
private static long[] ConvertToWordArray(string sMessage)
206
{
207
long[] ConvertToWordArray = null;
208
int lMessageLength = 0;
209
int lNumberOfWords = 0;
210
long[] lWordArray = null;
211
int lBytePosition = 0;
212
int lByteCount = 0;
213
int lWordCount = 0;
214
215
const int MODULUS_BITS = 512;
216
const int CONGRUENT_BITS = 448;
217
218
lMessageLength = sMessage.Length;
219
lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) / BITS_TO_A_BYTE)) / (MODULUS_BITS / BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS / BITS_TO_A_WORD);
220
lWordArray = new long[lNumberOfWords];
221
222
lBytePosition = 0;
223
lByteCount = 0;
224
225
while(lByteCount < lMessageLength)
226
{
227
lWordCount = lByteCount / BYTES_TO_A_WORD;
228
lBytePosition = (lByteCount % BYTES_TO_A_WORD) * BITS_TO_A_BYTE;
229
lWordArray[lWordCount] = lWordArray[lWordCount] | LShift(Convert.ToByte(sMessage.Substring(lByteCount, 1).ToCharArray()[0]), lBytePosition);
230
lByteCount = lByteCount + 1;
231
}
232
233
lWordCount = lByteCount / BYTES_TO_A_WORD;
234
lBytePosition = (lByteCount % BYTES_TO_A_WORD) * BITS_TO_A_BYTE;
235
lWordArray[lWordCount] = lWordArray[lWordCount] | LShift(0x80, lBytePosition);
236
lWordArray[lNumberOfWords - 2] = LShift(lMessageLength, 3);
237
lWordArray[lNumberOfWords - 1] = RShift(lMessageLength, 29);
238
ConvertToWordArray = lWordArray;
239
240
return ConvertToWordArray;
241
}
242
243
private static string WordToHex(long lValue)
244
{
245
string WordToHex = "";
246
long lByte = 0;
247
int lCount = 0;
248
for(lCount = 0; lCount <= 3; lCount++)
249
{
250
lByte = RShift(lValue, lCount * BITS_TO_A_BYTE) & m_lOnBits[BITS_TO_A_BYTE - 1];
251
WordToHex = WordToHex + (("0" + ToHex(lByte)).Substring(("0" + ToHex(lByte)).Length - 2));
252
}
253
return WordToHex;
254
}
255
256
private static string ToHex(long dec)
257
{
258
string strhex = "";
259
while(dec > 0)
260
{
261
strhex = tohex(dec % 16) + strhex;
262
dec = dec / 16;
263
}
264
return strhex;
265
}
266
267
private static string tohex(long hex)
268
{
269
string strhex = "";
270
switch(hex)
271
{
272
case 10: strhex = "a"; break;
273
case 11: strhex = "b"; break;
274
case 12: strhex = "c"; break;
275
case 13: strhex = "d"; break;
276
case 14: strhex = "e"; break;
277
case 15: strhex = "f"; break;
278
default : strhex = hex.ToString(); break;
279
}
280
return strhex;
281
}
282
283
284
public static string Encrypt(string sMessage, int stype)
285
{
286
string MD5 = "";
287
288
for(int i=0; i<=30; i++)
289
{
290
m_lOnBits[i] = Convert.ToInt64(Math.Pow(2, i+1) -1);
291
m_l2Power[i] = Convert.ToInt64(Math.Pow(2, i));
292
}
293
294
long[] x = null;
295
int k = 0;
296
long AA = 0;
297
long BB = 0;
298
long CC = 0;
299
long DD = 0;
300
long a = 0;
301
long b = 0;
302
long c = 0;
303
long d = 0;
304
305
const int S11 = 7;
306
const int S12 = 12;
307
const int S13 = 17;
308
const int S14 = 22;
309
const int S21 = 5;
310
const int S22 = 9;
311
const int S23 = 14;
312
const int S24 = 20;
313
const int S31 = 4;
314
const int S32 = 11;
315
const int S33 = 16;
316
const int S34 = 23;
317
const int S41 = 6;
318
const int S42 = 10;
319
const int S43 = 15;
320
const int S44 = 21;
321
322
x = ConvertToWordArray(sMessage);
323
324
a = 0x67452301;
325
b = 0xEFCDAB89;
326
c = 0x98BADCFE;
327
d = 0x10325476;
328
329
for(k = 0; k < x.Length; k += 16)
330
{
331
AA = a;
332
BB = b;
333
CC = c;
334
DD = d;
335
336
md5_FF(ref a, b, c, d, x[k + 0], S11, 0xD76AA478);
337
md5_FF(ref d, a, b, c, x[k + 1], S12, 0xE8C7B756);
338
md5_FF(ref c, d, a, b, x[k + 2], S13, 0x242070DB);
339
md5_FF(ref b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
340
md5_FF(ref a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
341
md5_FF(ref d, a, b, c, x[k + 5], S12, 0x4787C62A);
342
md5_FF(ref c, d, a, b, x[k + 6], S13, 0xA8304613);
343
md5_FF(ref b, c, d, a, x[k + 7], S14, 0xFD469501);
344
md5_FF(ref a, b, c, d, x[k + 8], S11, 0x698098D8);
345
md5_FF(ref d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
346
md5_FF(ref c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
347
md5_FF(ref b, c, d, a, x[k + 11], S14, 0x895CD7BE);
348
md5_FF(ref a, b, c, d, x[k + 12], S11, 0x6B901122);
349
md5_FF(ref d, a, b, c, x[k + 13], S12, 0xFD987193);
350
md5_FF(ref c, d, a, b, x[k + 14], S13, 0xA679438E);
351
md5_FF(ref b, c, d, a, x[k + 15], S14, 0x49B40821);
352
md5_GG(ref a, b, c, d, x[k + 1], S21, 0xF61E2562);
353
md5_GG(ref d, a, b, c, x[k + 6], S22, 0xC040B340);
354
md5_GG(ref c, d, a, b, x[k + 11], S23, 0x265E5A51);
355
md5_GG(ref b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
356
md5_GG(ref a, b, c, d, x[k + 5], S21, 0xD62F105D);
357
md5_GG(ref d, a, b, c, x[k + 10], S22, 0x2441453);
358
md5_GG(ref c, d, a, b, x[k + 15], S23, 0xD8A1E681);
359
md5_GG(ref b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
360
md5_GG(ref a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
361
md5_GG(ref d, a, b, c, x[k + 14], S22, 0xC33707D6);
362
md5_GG(ref c, d, a, b, x[k + 3], S23, 0xF4D50D87);
363
md5_GG(ref b, c, d, a, x[k + 8], S24, 0x455A14ED);
364
md5_GG(ref a, b, c, d, x[k + 13], S21, 0xA9E3E905);
365
md5_GG(ref d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
366
md5_GG(ref c, d, a, b, x[k + 7], S23, 0x676F02D9);
367
md5_GG(ref b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
368
md5_HH(ref a, b, c, d, x[k + 5], S31, 0xFFFA3942);
369
md5_HH(ref d, a, b, c, x[k + 8], S32, 0x8771F681);
370
md5_HH(ref c, d, a, b, x[k + 11], S33, 0x6D9D6122);
371
md5_HH(ref b, c, d, a, x[k + 14], S34, 0xFDE5380C);
372
md5_HH(ref a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
373
md5_HH(ref d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
374
md5_HH(ref c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
375
md5_HH(ref b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
376
md5_HH(ref a, b, c, d, x[k + 13], S31, 0x289B7EC6);
377
md5_HH(ref d, a, b, c, x[k + 0], S32, 0xEAA127FA);
378
md5_HH(ref c, d, a, b, x[k + 3], S33, 0xD4EF3085);
379
md5_HH(ref b, c, d, a, x[k + 6], S34, 0x4881D05);
380
md5_HH(ref a, b, c, d, x[k + 9], S31, 0xD9D4D039);
381
md5_HH(ref d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
382
md5_HH(ref c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
383
md5_HH(ref b, c, d, a, x[k + 2], S34, 0xC4AC5665);
384
md5_II(ref a, b, c, d, x[k + 0], S41, 0xF4292244);
385
md5_II(ref d, a, b, c, x[k + 7], S42, 0x432AFF97);
386
md5_II(ref c, d, a, b, x[k + 14], S43, 0xAB9423A7);
387
md5_II(ref b, c, d, a, x[k + 5], S44, 0xFC93A039);
388
md5_II(ref a, b, c, d, x[k + 12], S41, 0x655B59C3);
389
md5_II(ref d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
390
md5_II(ref c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
391
md5_II(ref b, c, d, a, x[k + 1], S44, 0x85845DD1);
392
md5_II(ref a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
393
md5_II(ref d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
394
md5_II(ref c, d, a, b, x[k + 6], S43, 0xA3014314);
395
md5_II(ref b, c, d, a, x[k + 13], S44, 0x4E0811A1);
396
md5_II(ref a, b, c, d, x[k + 4], S41, 0xF7537E82);
397
md5_II(ref d, a, b, c, x[k + 11], S42, 0xBD3AF235);
398
md5_II(ref c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
399
md5_II(ref b, c, d, a, x[k + 9], S44, 0xEB86D391);
400
401
a = AddUnsigned(a, AA);
402
b = AddUnsigned(b, BB);
403
c = AddUnsigned(c, CC);
404
d = AddUnsigned(d, DD);
405
}
406
407
if (stype == 32)
408
{
409
MD5 = ((((WordToHex(a)) + (WordToHex(b))) + (WordToHex(c))) + (WordToHex(d))).ToLower();
410
}
411
else
412
{
413
MD5 = ((WordToHex(b)) + (WordToHex(c))).ToLower();
414
}
415
return MD5;
416
}
417
}
418
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418