KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > matuschek > util > MD5


1 /*
2  * MD5 in Java JDK Beta-2
3  * written Santeri Paavolainen, Helsinki Finland 1996
4  * (c) Santeri Paavolainen, Helsinki Finland 1996
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * See http://www.cs.hut.fi/~santtu/java/ for more information on this
21  * class.
22  *
23  * This is rather straight re-implementation of the reference implementation
24  * given in RFC1321 by RSA.
25  *
26  * Passes MD5 test suite as defined in RFC1321.
27  *
28  *
29  * This Java class has been derived from the RSA Data Security, Inc. MD5
30  * Message-Digest Algorithm and its reference implementation.
31  *
32  *
33  * Moved to the net.matuschek.util package for JoBo integration
34  * replaced deprecated use of String.getBytes()
35  */

36 package net.matuschek.util;
37
38 /**
39  * Contains internal state of the MD5 class
40  */

41
42 class MD5State {
43   /**
44    * 128-byte state
45    */

46   int state[];
47
48   /**
49    * 64-bit character count (could be true Java long?)
50    */

51   int count[];
52
53   /**
54    * 64-byte buffer (512 bits) for storing to-be-hashed characters
55    */

56   byte buffer[];
57
58   public MD5State() {
59     buffer = new byte[64];
60     count = new int[2];
61     state = new int[4];
62     
63     state[0] = 0x67452301;
64     state[1] = 0xefcdab89;
65     state[2] = 0x98badcfe;
66     state[3] = 0x10325476;
67
68     count[0] = count[1] = 0;
69   }
70
71   /** Create this State as a copy of another state */
72   public MD5State (MD5State from) {
73     this();
74
75     int i;
76
77     for (i = 0; i < buffer.length; i++)
78       this.buffer[i] = from.buffer[i];
79     
80     for (i = 0; i < state.length; i++)
81       this.state[i] = from.state[i];
82
83     for (i = 0; i < count.length; i++)
84       this.count[i] = from.count[i];
85   }
86 };
87
88
89 /**
90  * Implementation of RSA's MD5 hash generator
91  *
92  * @version $Revision: 1.1 $
93  * @author Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
94  */

95 public class MD5 {
96   /**
97    * MD5 state
98    */

99   MD5State state;
100  
101   /**
102    * If Final() has been called, finals is set to the current finals
103    * state. Any Update() causes this to be set to null.
104    */

105   MD5State finals;
106
107   /**
108    * Padding for Final()
109    */

110   static byte padding[] = {
111     (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
114   };
115
116   /**
117    * Initialize MD5 internal state (object can be reused just by
118    * calling Init() after every Final()
119    */

120   public synchronized void Init () {
121     state = new MD5State();
122     finals = null;
123   }
124
125   /**
126    * Class constructor
127    */

128   public MD5 () {
129     this.Init();
130   }
131
132   /**
133    * Initialize class, and update hash with ob.toString()
134    *
135    * @param ob Object, ob.toString() is used to update hash
136    * after initialization
137    */

138   public MD5 (Object JavaDoc ob) {
139     this();
140     Update(ob.toString());
141   }
142   
143   private int rotate_left (int x, int n) {
144     return (x << n) | (x >>> (32 - n));
145   }
146
147   /* I wonder how many loops and hoops you'll have to go through to
148      get unsigned add for longs in java */

149
150   private int uadd (int a, int b) {
151     long aa, bb;
152     aa = ((long) a) & 0xffffffffL;
153     bb = ((long) b) & 0xffffffffL;
154     
155     aa += bb;
156
157     return (int) (aa & 0xffffffffL);
158   }
159
160   private int uadd (int a, int b, int c) {
161     return uadd(uadd(a, b), c);
162   }
163
164   private int uadd (int a, int b, int c, int d) {
165     return uadd(uadd(a, b, c), d);
166   }
167
168   private int FF (int a, int b, int c, int d, int x, int s, int ac) {
169     a = uadd(a, ((b & c) | (~b & d)), x, ac);
170     return uadd(rotate_left(a, s), b);
171   }
172
173   private int GG (int a, int b, int c, int d, int x, int s, int ac) {
174     a = uadd(a, ((b & d) | (c & ~d)), x, ac);
175     return uadd(rotate_left(a, s), b);
176   }
177
178   private int HH (int a, int b, int c, int d, int x, int s, int ac) {
179     a = uadd(a, (b ^ c ^ d), x, ac);
180     return uadd(rotate_left(a, s) , b);
181   }
182
183   private int II (int a, int b, int c, int d, int x, int s, int ac) {
184     a = uadd(a, (c ^ (b | ~d)), x, ac);
185     return uadd(rotate_left(a, s), b);
186   }
187
188   private int[] Decode (byte buffer[], int len, int shift) {
189     int out[];
190     int i, j;
191
192     out = new int[16];
193
194     for (i = j = 0; j < len; i++, j += 4) {
195       out[i] = ((int) (buffer[j + shift] & 0xff)) |
196     (((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
197     (((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
198     (((int) (buffer[j + 3 + shift] & 0xff)) << 24);
199
200 /* System.out.println("out[" + i + "] = \t" +
201              ((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
202              ((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
203              ((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
204              ((int) buffer[j + 3 + shift] & 0xff));*/

205     }
206     
207     return out;
208   }
209
210   private void Transform (MD5State state, byte buffer[], int shift) {
211     int
212       a = state.state[0],
213       b = state.state[1],
214       c = state.state[2],
215       d = state.state[3],
216       x[];
217
218     x = Decode(buffer, 64, shift);
219        
220     /* Round 1 */
221     a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
222     d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
223     c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
224     b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
225     a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
226     d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
227     c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
228     b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
229     a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
230     d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
231     c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
232     b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
233     a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
234     d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
235     c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
236     b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
237
238     /* Round 2 */
239     a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
240     d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
241     c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
242     b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
243     a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
244     d = GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */
245     c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
246     b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
247     a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
248     d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
249     c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
250     b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
251     a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
252     d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
253     c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
254     b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
255
256     /* Round 3 */
257     a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
258     d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
259     c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
260     b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
261     a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
262     d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
263     c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
264     b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
265     a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
266     d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
267     c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
268     b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
269     a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
270     d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
271     c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
272     b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
273
274     /* Round 4 */
275     a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
276     d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
277     c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
278     b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
279     a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
280     d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
281     c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
282     b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
283     a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
284     d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
285     c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
286     b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
287     a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
288     d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
289     c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
290     b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
291
292     state.state[0] += a;
293     state.state[1] += b;
294     state.state[2] += c;
295     state.state[3] += d;
296   }
297
298   /**
299    * Updates hash with the bytebuffer given (using at maximum length bytes from
300    * that buffer)
301    *
302    * @param state Which state is updated
303    * @param buffer Array of bytes to be hashed
304    * @param offset Offset to buffer array
305    * @param length Use at maximum `length' bytes (absolute
306    * maximum is buffer.length)
307    */

308   public void Update (MD5State stat, byte buffer[], int offset, int length) {
309     int index, partlen, i, start;
310
311     finals = null;
312
313     /* Length can be told to be shorter, but not inter */
314     if ((length - offset)> buffer.length)
315       length = buffer.length - offset;
316
317     /* compute number of bytes mod 64 */
318     index = (int) (stat.count[0] >>> 3) & 0x3f;
319
320     if ((stat.count[0] += (length << 3)) <
321     (length << 3))
322       stat.count[1]++;
323
324     stat.count[1] += length >>> 29;
325
326     partlen = 64 - index;
327
328     if (length >= partlen) {
329       for (i = 0; i < partlen; i++)
330     stat.buffer[i + index] = buffer[i + offset];
331
332       Transform(stat, stat.buffer, 0);
333     
334       for (i = partlen; (i + 63) < length; i+= 64)
335     Transform(stat, buffer, i);
336
337       index = 0;
338     } else
339       i = 0;
340
341     /* buffer remaining input */
342     if (i < length) {
343       start = i;
344       for (; i < length; i++)
345     stat.buffer[index + i - start] = buffer[i + offset];
346     }
347   }
348
349   /*
350    * Update()s for other datatypes than byte[] also. Update(byte[], int)
351    * is only the main driver.
352    */

353
354   /**
355    * Plain update, updates this object
356    */

357
358   public void Update (byte buffer[], int offset, int length) {
359       Update(this.state, buffer, offset, length);
360   }
361
362   public void Update (byte buffer[], int length) {
363       Update(this.state, buffer, 0, length);
364   }
365
366   /**
367    * Updates hash with given array of bytes
368    *
369    * @param buffer Array of bytes to use for updating the hash
370    */

371   public void Update (byte buffer[]) {
372       Update(buffer, 0, buffer.length);
373   }
374
375   /**
376    * Updates hash with a single byte
377    *
378    * @param b Single byte to update the hash
379    */

380   public void Update (byte b) {
381     byte buffer[] = new byte[1];
382     buffer[0] = b;
383
384     Update(buffer, 1);
385   }
386   
387   /**
388    * Update buffer with given string.
389    *
390    * @param s String to be update to hash (is used as
391    * s.getBytes())
392    */

393   public void Update (String JavaDoc s) {
394     byte chars[];
395
396     chars = s.getBytes();
397
398     Update(chars, chars.length);
399   }
400
401   /**
402    * Update buffer with a single integer (only & 0xff part is used,
403    * as a byte)
404    *
405    * @param i Integer value, which is then converted to
406    * byte as i & 0xff
407    */

408
409   public void Update (int i) {
410       Update((byte) (i & 0xff));
411   }
412
413   private byte[] Encode (int input[], int len) {
414     int i, j;
415     byte out[];
416
417     out = new byte[len];
418
419     for (i = j = 0; j < len; i++, j += 4) {
420       out[j] = (byte) (input[i] & 0xff);
421       out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
422       out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
423       out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
424     }
425
426     return out;
427   }
428
429   /**
430    * Returns array of bytes (16 bytes) representing hash as of the
431    * current state of this object. Note: getting a hash does not
432    * invalidate the hash object, it only creates a copy of the real
433    * state which is finalized.
434    *
435    * @return Array of 16 bytes, the hash of all updated bytes
436    */

437   public synchronized byte[] Final () {
438     byte bits[];
439     int index, padlen;
440     MD5State fin;
441
442     if (finals == null) {
443       fin = new MD5State(state);
444
445       bits = Encode(fin.count, 8);
446     
447       index = (int) ((fin.count[0] >>> 3) & 0x3f);
448       padlen = (index < 56) ? (56 - index) : (120 - index);
449
450       Update(fin, padding, 0, padlen);
451       /**/
452       Update(fin, bits, 0, 8);
453
454       /* Update() sets finalds to null */
455       finals = fin;
456     }
457
458     return Encode(finals.state, 16);
459   }
460
461   /**
462    * Turns array of bytes into string representing each byte as
463    * unsigned hex number.
464    *
465    * @param hash Array of bytes to convert to hex-string
466    * @return Generated hex string
467    */

468   public static String JavaDoc asHex (byte hash[]) {
469     StringBuffer JavaDoc buf = new StringBuffer JavaDoc(hash.length * 2);
470     int i;
471
472     for (i = 0; i < hash.length; i++) {
473       if (((int) hash[i] & 0xff) < 0x10)
474     buf.append("0");
475
476       buf.append(Long.toString((int) hash[i] & 0xff, 16));
477     }
478
479     return buf.toString();
480   }
481
482   /**
483    * Returns 32-character hex representation of this objects hash
484    *
485    * @return String of this object's hash
486    */

487   public String JavaDoc asHex () {
488     return asHex(this.Final());
489   }
490 }
491
492
493
Popular Tags