1 package com.knowgate.misc; 2 3 import com.knowgate.debug.DebugFile; 4 5 42 43 46 47 class MD5State { 48 51 int state[]; 52 53 56 int count[]; 57 58 61 byte buffer[]; 62 63 public MD5State() { 64 buffer = new byte[64]; 65 count = new int[2]; 66 state = new int[4]; 67 68 state[0] = 0x67452301; 69 state[1] = 0xefcdab89; 70 state[2] = 0x98badcfe; 71 state[3] = 0x10325476; 72 73 count[0] = count[1] = 0; 74 } 75 76 77 public MD5State (MD5State from) { 78 this(); 79 80 int i; 81 82 for (i = 0; i < buffer.length; i++) 83 this.buffer[i] = from.buffer[i]; 84 85 for (i = 0; i < state.length; i++) 86 this.state[i] = from.state[i]; 87 88 for (i = 0; i < count.length; i++) 89 this.count[i] = from.count[i]; 90 } 91 } 92 93 99 100 public class MD5 { 101 104 MD5State state; 105 106 110 MD5State finals; 111 112 115 static byte padding[] = { 116 (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 119 }; 120 121 125 public synchronized void Init () { 126 state = new MD5State(); 127 finals = null; 128 } 129 130 133 public MD5 () { 134 this.Init(); 135 } 136 137 143 public MD5 (Object ob) { 144 this(); 145 Update(ob.toString()); 146 } 147 148 private int rotate_left (int x, int n) { 149 return (x << n) | (x >>> (32 - n)); 150 } 151 152 154 155 private int uadd (int a, int b) { 156 long aa, bb; 157 aa = ((long) a) & 0xffffffffL; 158 bb = ((long) b) & 0xffffffffL; 159 160 aa += bb; 161 162 return (int) (aa & 0xffffffffL); 163 } 164 165 private int uadd (int a, int b, int c) { 166 return uadd(uadd(a, b), c); 167 } 168 169 private int uadd (int a, int b, int c, int d) { 170 return uadd(uadd(a, b, c), d); 171 } 172 173 private int FF (int a, int b, int c, int d, int x, int s, int ac) { 174 a = uadd(a, ((b & c) | (~b & d)), x, ac); 175 return uadd(rotate_left(a, s), b); 176 } 177 178 private int GG (int a, int b, int c, int d, int x, int s, int ac) { 179 a = uadd(a, ((b & d) | (c & ~d)), x, ac); 180 return uadd(rotate_left(a, s), b); 181 } 182 183 private int HH (int a, int b, int c, int d, int x, int s, int ac) { 184 a = uadd(a, (b ^ c ^ d), x, ac); 185 return uadd(rotate_left(a, s) , b); 186 } 187 188 private int II (int a, int b, int c, int d, int x, int s, int ac) { 189 a = uadd(a, (c ^ (b | ~d)), x, ac); 190 return uadd(rotate_left(a, s), b); 191 } 192 193 private int[] Decode (byte buffer[], int len, int shift) { 194 int out[]; 195 int i, j; 196 197 out = new int[16]; 198 199 for (i = j = 0; j < len; i++, j += 4) { 200 out[i] = ((int) (buffer[j + shift] & 0xff)) | 201 (((int) (buffer[j + 1 + shift] & 0xff)) << 8) | 202 (((int) (buffer[j + 2 + shift] & 0xff)) << 16) | 203 (((int) (buffer[j + 3 + shift] & 0xff)) << 24); 204 205 210 } 211 212 return out; 213 } 214 215 private void Transform (MD5State state, byte buffer[], int shift) { 216 int 217 a = state.state[0], 218 b = state.state[1], 219 c = state.state[2], 220 d = state.state[3], 221 x[]; 222 223 x = Decode(buffer, 64, shift); 224 225 226 a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); 227 d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); 228 c = FF (c, d, a, b, x[ 2], 17, 0x242070db); 229 b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); 230 a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); 231 d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); 232 c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); 233 b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); 234 a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); 235 d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); 236 c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); 237 b = FF (b, c, d, a, x[11], 22, 0x895cd7be); 238 a = FF (a, b, c, d, x[12], 7, 0x6b901122); 239 d = FF (d, a, b, c, x[13], 12, 0xfd987193); 240 c = FF (c, d, a, b, x[14], 17, 0xa679438e); 241 b = FF (b, c, d, a, x[15], 22, 0x49b40821); 242 243 244 a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); 245 d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); 246 c = GG (c, d, a, b, x[11], 14, 0x265e5a51); 247 b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); 248 a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); 249 d = GG (d, a, b, c, x[10], 9, 0x2441453); 250 c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); 251 b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); 252 a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); 253 d = GG (d, a, b, c, x[14], 9, 0xc33707d6); 254 c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); 255 b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); 256 a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); 257 d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); 258 c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); 259 b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); 260 261 262 a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); 263 d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); 264 c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); 265 b = HH (b, c, d, a, x[14], 23, 0xfde5380c); 266 a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); 267 d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); 268 c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); 269 b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); 270 a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); 271 d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); 272 c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); 273 b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); 274 a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); 275 d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); 276 c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); 277 b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); 278 279 280 a = II (a, b, c, d, x[ 0], 6, 0xf4292244); 281 d = II (d, a, b, c, x[ 7], 10, 0x432aff97); 282 c = II (c, d, a, b, x[14], 15, 0xab9423a7); 283 b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); 284 a = II (a, b, c, d, x[12], 6, 0x655b59c3); 285 d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); 286 c = II (c, d, a, b, x[10], 15, 0xffeff47d); 287 b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); 288 a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); 289 d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); 290 c = II (c, d, a, b, x[ 6], 15, 0xa3014314); 291 b = II (b, c, d, a, x[13], 21, 0x4e0811a1); 292 a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); 293 d = II (d, a, b, c, x[11], 10, 0xbd3af235); 294 c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); 295 b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); 296 297 state.state[0] += a; 298 state.state[1] += b; 299 state.state[2] += c; 300 state.state[3] += d; 301 } 302 303 313 public void Update (MD5State stat, byte buffer[], int offset, int length) 314 throws NullPointerException { 315 int index, partlen, i, start; 316 317 if (null==buffer) throw new NullPointerException ("Array of bytes to be hashed may not be null"); 318 319 if (DebugFile.trace) { 320 DebugFile.writeln("Begin MD5.Update([MD5State],byte[],"+String.valueOf(offset)+","+String.valueOf(length)+")"); 321 DebugFile.incIdent(); 322 } 323 324 finals = null; 325 326 327 if ((length - offset)> buffer.length) 328 length = buffer.length - offset; 329 330 331 index = (int) (stat.count[0] >>> 3) & 0x3f; 332 333 if ((stat.count[0] += (length << 3)) < 334 (length << 3)) 335 stat.count[1]++; 336 337 stat.count[1] += length >>> 29; 338 339 partlen = 64 - index; 340 341 if (length >= partlen) { 342 for (i = 0; i < partlen; i++) 343 stat.buffer[i + index] = buffer[i + offset]; 344 345 Transform(stat, stat.buffer, 0); 346 347 for (i = partlen; (i + 63) < length; i+= 64) 348 Transform(stat, buffer, i); 349 350 index = 0; 351 } else 352 i = 0; 353 354 355 if (i < length) { 356 start = i; 357 for (; i < length; i++) 358 stat.buffer[index + i - start] = buffer[i + offset]; 359 } 360 361 if (DebugFile.trace) { 362 DebugFile.decIdent(); 363 DebugFile.writeln("End MD5.Update()"); 364 } 365 } 367 371 372 375 376 public void Update (byte buffer[], int offset, int length) { 377 Update(this.state, buffer, offset, length); 378 } 379 380 public void Update (byte buffer[], int length) { 381 Update(this.state, buffer, 0, length); 382 } 383 384 389 public void Update (byte buffer[]) throws NullPointerException { 390 if (null==buffer) throw new NullPointerException ("Array of bytes to be hashed may not be null"); 391 392 Update(buffer, 0, buffer.length); 393 } 394 395 400 public void Update (byte b) { 401 byte buffer[] = new byte[1]; 402 buffer[0] = b; 403 404 Update(buffer, 1); 405 } 406 407 413 public void Update (String s) { 414 byte chars[]; 415 416 try { 419 chars = s.getBytes("UTF-8"); 420 } catch(java.io.UnsupportedEncodingException ex) { 421 ex.printStackTrace(); 423 chars = new byte[1]; 424 } 425 426 Update(chars, chars.length); 427 } 428 429 436 437 public void Update (int i) { 438 Update((byte) (i & 0xff)); 439 } 440 441 private byte[] Encode (int input[], int len) { 442 int i, j; 443 byte out[]; 444 445 out = new byte[len]; 446 447 for (i = j = 0; j < len; i++, j += 4) { 448 out[j] = (byte) (input[i] & 0xff); 449 out[j + 1] = (byte) ((input[i] >>> 8) & 0xff); 450 out[j + 2] = (byte) ((input[i] >>> 16) & 0xff); 451 out[j + 3] = (byte) ((input[i] >>> 24) & 0xff); 452 } 453 454 return out; 455 } 456 457 465 public synchronized byte[] Final () { 466 byte bits[]; 467 int index, padlen; 468 MD5State fin; 469 470 if (finals == null) { 471 fin = new MD5State(state); 472 473 bits = Encode(fin.count, 8); 474 475 index = (int) ((fin.count[0] >>> 3) & 0x3f); 476 padlen = (index < 56) ? (56 - index) : (120 - index); 477 478 Update(fin, padding, 0, padlen); 479 480 Update(fin, bits, 0, 8); 481 482 483 finals = fin; 484 } 485 486 byte[] byRetArray = Encode(finals.state, 16); 487 488 if (DebugFile.trace) DebugFile.writeln("MD5.Final() : " + Gadgets.toHexString(byRetArray)); 489 490 return byRetArray; 491 } 492 493 500 public static String asHex (byte hash[]) { 501 StringBuffer buf = new StringBuffer (hash.length * 2); 502 int i; 503 504 for (i = 0; i < hash.length; i++) { 505 if (((int) hash[i] & 0xff) < 0x10) 506 buf.append("0"); 507 508 buf.append(Long.toString((int) hash[i] & 0xff, 16)); 509 } 510 511 return buf.toString(); 512 } 513 514 519 public String asHex () { 520 return asHex(this.Final()); 521 } 522 } 523 | Popular Tags |