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