Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: plugins/MsnService/MD5.java


1   package plugins.MsnService;
2   
3   /*
4    * $Header: /cvsroot/jdexter/plugins/MsnService/Attic/MD5.java,v 1.1.1.1 2002/10/16 22:10:49 tobias_r Exp $
5    *
6    * MD5 in Java JDK Beta-2
7    * written Santeri Paavolainen, Helsinki Finland 1996
8    * (c) Santeri Paavolainen, Helsinki Finland 1996
9    *
10   * This library is free software; you can redistribute it and/or
11   * modify it under the terms of the GNU Library General Public
12   * License as published by the Free Software Foundation; either
13   * version 2 of the License, or (at your option) any later version.
14   *
15   * This library is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   * Library General Public License for more details.
19   *
20   * You should have received a copy of the GNU Library General Public
21   * License along with this library; if not, write to the Free
22   * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23   *
24   * See http://www.cs.hut.fi/~santtu/java/ for more information on this
25   * class.
26   *
27   * This is rather straight re-implementation of the reference implementation
28   * given in RFC1321 by RSA.
29   *
30   * Passes MD5 test suite as defined in RFC1321.
31   *
32   *
33   * This Java class has been derived from the RSA Data Security, Inc. MD5
34   * Message-Digest Algorithm and its reference implementation.
35   *
36   *
37   * $Log: MD5.java,v $
38   * Revision 1.1.1.1  2002/10/16 22:10:49  tobias_r
39   *
40   *
41   * Revision 1.5  1996/12/12 10:47:02  santtu
42   * Changed GPL to LGPL
43   *
44   * Revision 1.4  1996/12/12 10:30:02  santtu
45   * Some typos, State -> MD5State etc.
46   *
47   * Revision 1.3  1996/04/15 07:28:09  santtu
48   * Added GPL statemets, and RSA derivate stametemetsnnts.
49   *
50   * Revision 1.2  1996/03/04 08:05:48  santtu
51   * Added offsets to Update method
52   *
53   * Revision 1.1  1996/01/07 20:51:59  santtu
54   * Initial revision
55   *
56   */
57  
58  /**
59   * Contains internal state of the MD5 class
60   */
61  
62  class MD5State {
63    /**
64     * 128-byte state
65     */
66    int  state[];
67  
68    /**
69     * 64-bit character count (could be true Java long?)
70     */
71    int  count[];
72  
73    /**
74     * 64-byte buffer (512 bits) for storing to-be-hashed characters
75     */
76    byte  buffer[];
77  
78    public MD5State() {
79      buffer = new byte[64];
80      count = new int[2];
81      state = new int[4];
82  
83      state[0] = 0x67452301;
84      state[1] = 0xefcdab89;
85      state[2] = 0x98badcfe;
86      state[3] = 0x10325476;
87  
88      count[0] = count[1] = 0;
89    }
90  
91    /** Create this State as a copy of another state */
92    public MD5State (MD5State from) {
93      this();
94  
95      int i;
96  
97      for (i = 0; i < buffer.length; i++)
98        this.buffer[i] = from.buffer[i];
99  
100     for (i = 0; i < state.length; i++)
101       this.state[i] = from.state[i];
102 
103     for (i = 0; i < count.length; i++)
104       this.count[i] = from.count[i];
105   }
106 };
107 
108 /**
109  * Implementation of RSA's MD5 hash generator
110  *
111  * @version  $Revision: 1.1.1.1 $
112  * @author  Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
113  */
114 
115 public class MD5 {
116   /**
117    * MD5 state
118    */
119   MD5State  state;
120 
121   /**
122    * If Final() has been called, finals is set to the current finals
123    * state. Any Update() causes this to be set to null.
124    */
125   MD5State   finals;
126 
127   /**
128    * Padding for Final()
129    */
130   static byte  padding[] = {
131     (byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
134   };
135 
136   /**
137    * Initialize MD5 internal state (object can be reused just by
138    * calling Init() after every Final()
139    */
140   public synchronized void Init () {
141     state = new MD5State();
142     finals = null;
143   }
144 
145   /**
146    * Class constructor
147    */
148   public MD5 () {
149     this.Init();
150   }
151 
152   /**
153    * Initialize class, and update hash with ob.toString()
154    *
155    * @param  ob  Object, ob.toString() is used to update hash
156    *      after initialization
157    */
158   public MD5 (Object ob) {
159     this();
160     Update(ob.toString());
161   }
162 
163   private int rotate_left (int x, int n) {
164     return (x << n) | (x >>> (32 - n));
165   }
166 
167   /* I wonder how many loops and hoops you'll have to go through to
168      get unsigned add for longs in java */
169 
170   private int uadd (int a, int b) {
171     long aa, bb;
172     aa = ((long) a) & 0xffffffffL;
173     bb = ((long) b) & 0xffffffffL;
174 
175     aa += bb;
176 
177     return (int) (aa & 0xffffffffL);
178   }
179 
180   private int uadd (int a, int b, int c) {
181     return uadd(uadd(a, b), c);
182   }
183 
184   private int uadd (int a, int b, int c, int d) {
185     return uadd(uadd(a, b, c), d);
186   }
187 
188   private int FF (int a, int b, int c, int d, int x, int s, int ac) {
189     a = uadd(a, ((b & c) | (~b & d)), x, ac);
190     return uadd(rotate_left(a, s), b);
191   }
192 
193   private int GG (int a, int b, int c, int d, int x, int s, int ac) {
194     a = uadd(a, ((b & d) | (c & ~d)), x, ac);
195     return uadd(rotate_left(a, s), b);
196   }
197 
198   private int HH (int a, int b, int c, int d, int x, int s, int ac) {
199     a = uadd(a, (b ^ c ^ d), x, ac);
200     return uadd(rotate_left(a, s) , b);
201   }
202 
203   private int II (int a, int b, int c, int d, int x, int s, int ac) {
204     a = uadd(a, (c ^ (b | ~d)), x, ac);
205     return uadd(rotate_left(a, s), b);
206   }
207 
208   private int[] Decode (byte buffer[], int len, int shift) {
209     int    out[];
210     int   i, j;
211 
212     out = new int[16];
213 
214     for (i = j = 0; j < len; i++, j += 4) {
215       out[i] = ((int) (buffer[j + shift] & 0xff)) |
216   (((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
217   (((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
218   (((int) (buffer[j + 3 + shift] & 0xff)) << 24);
219 
220 /*      System.out.println("out[" + i + "] = \t" +
221        ((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
222        ((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
223        ((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
224        ((int) buffer[j + 3 + shift] & 0xff));*/
225     }
226 
227     return out;
228   }
229 
230   private void Transform (MD5State state, byte buffer[], int shift) {
231     int
232       a = state.state[0],
233       b = state.state[1],
234       c = state.state[2],
235       d = state.state[3],
236       x[];
237 
238     x = Decode(buffer, 64, shift);
239 
240     /* Round 1 */
241     a = FF (a, b, c, d, x[ 0],   7, 0xd76aa478); /* 1 */
242     d = FF (d, a, b, c, x[ 1],  12, 0xe8c7b756); /* 2 */
243     c = FF (c, d, a, b, x[ 2],  17, 0x242070db); /* 3 */
244     b = FF (b, c, d, a, x[ 3],  22, 0xc1bdceee); /* 4 */
245     a = FF (a, b, c, d, x[ 4],   7, 0xf57c0faf); /* 5 */
246     d = FF (d, a, b, c, x[ 5],  12, 0x4787c62a); /* 6 */
247     c = FF (c, d, a, b, x[ 6],  17, 0xa8304613); /* 7 */
248     b = FF (b, c, d, a, x[ 7],  22, 0xfd469501); /* 8 */
249     a = FF (a, b, c, d, x[ 8],   7, 0x698098d8); /* 9 */
250     d = FF (d, a, b, c, x[ 9],  12, 0x8b44f7af); /* 10 */
251     c = FF (c, d, a, b, x[10],  17, 0xffff5bb1); /* 11 */
252     b = FF (b, c, d, a, x[11],  22, 0x895cd7be); /* 12 */
253     a = FF (a, b, c, d, x[12],   7, 0x6b901122); /* 13 */
254     d = FF (d, a, b, c, x[13],  12, 0xfd987193); /* 14 */
255     c = FF (c, d, a, b, x[14],  17, 0xa679438e); /* 15 */
256     b = FF (b, c, d, a, x[15],  22, 0x49b40821); /* 16 */
257 
258     /* Round 2 */
259     a = GG (a, b, c, d, x[ 1],   5, 0xf61e2562); /* 17 */
260     d = GG (d, a, b, c, x[ 6],   9, 0xc040b340); /* 18 */
261     c = GG (c, d, a, b, x[11],  14, 0x265e5a51); /* 19 */
262     b = GG (b, c, d, a, x[ 0],  20, 0xe9b6c7aa); /* 20 */
263     a = GG (a, b, c, d, x[ 5],   5, 0xd62f105d); /* 21 */
264     d = GG (d, a, b, c, x[10],   9,  0x2441453); /* 22 */
265     c = GG (c, d, a, b, x[15],  14, 0xd8a1e681); /* 23 */
266     b = GG (b, c, d, a, x[ 4],  20, 0xe7d3fbc8); /* 24 */
267     a = GG (a, b, c, d, x[ 9],   5, 0x21e1cde6); /* 25 */
268     d = GG (d, a, b, c, x[14],   9, 0xc33707d6); /* 26 */
269     c = GG (c, d, a, b, x[ 3],  14, 0xf4d50d87); /* 27 */
270     b = GG (b, c, d, a, x[ 8],  20, 0x455a14ed); /* 28 */
271     a = GG (a, b, c, d, x[13],   5, 0xa9e3e905); /* 29 */
272     d = GG (d, a, b, c, x[ 2],   9, 0xfcefa3f8); /* 30 */
273     c = GG (c, d, a, b, x[ 7],  14, 0x676f02d9); /* 31 */
274     b = GG (b, c, d, a, x[12],  20, 0x8d2a4c8a); /* 32 */
275 
276     /* Round 3 */
277     a = HH (a, b, c, d, x[ 5],   4, 0xfffa3942); /* 33 */
278     d = HH (d, a, b, c, x[ 8],  11, 0x8771f681); /* 34 */
279     c = HH (c, d, a, b, x[11],  16, 0x6d9d6122); /* 35 */
280     b = HH (b, c, d, a, x[14],  23, 0xfde5380c); /* 36 */
281     a = HH (a, b, c, d, x[ 1],   4, 0xa4beea44); /* 37 */
282     d = HH (d, a, b, c, x[ 4],  11, 0x4bdecfa9); /* 38 */
283     c = HH (c, d, a, b, x[ 7],  16, 0xf6bb4b60); /* 39 */
284     b = HH (b, c, d, a, x[10],  23, 0xbebfbc70); /* 40 */
285     a = HH (a, b, c, d, x[13],   4, 0x289b7ec6); /* 41 */
286     d = HH (d, a, b, c, x[ 0],  11, 0xeaa127fa); /* 42 */
287     c = HH (c, d, a, b, x[ 3],  16, 0xd4ef3085); /* 43 */
288     b = HH (b, c, d, a, x[ 6],  23,  0x4881d05); /* 44 */
289     a = HH (a, b, c, d, x[ 9],   4, 0xd9d4d039); /* 45 */
290     d = HH (d, a, b, c, x[12],  11, 0xe6db99e5); /* 46 */
291     c = HH (c, d, a, b, x[15],  16, 0x1fa27cf8); /* 47 */
292     b = HH (b, c, d, a, x[ 2],  23, 0xc4ac5665); /* 48 */
293 
294     /* Round 4 */
295     a = II (a, b, c, d, x[ 0],   6, 0xf4292244); /* 49 */
296     d = II (d, a, b, c, x[ 7],  10, 0x432aff97); /* 50 */
297     c = II (c, d, a, b, x[14],  15, 0xab9423a7); /* 51 */
298     b = II (b, c, d, a, x[ 5],  21, 0xfc93a039); /* 52 */
299     a = II (a, b, c, d, x[12],   6, 0x655b59c3); /* 53 */
300     d = II (d, a, b, c, x[ 3],  10, 0x8f0ccc92); /* 54 */
301     c = II (c, d, a, b, x[10],  15, 0xffeff47d); /* 55 */
302     b = II (b, c, d, a, x[ 1],  21, 0x85845dd1); /* 56 */
303     a = II (a, b, c, d, x[ 8],   6, 0x6fa87e4f); /* 57 */
304     d = II (d, a, b, c, x[15],  10, 0xfe2ce6e0); /* 58 */
305     c = II (c, d, a, b, x[ 6],  15, 0xa3014314); /* 59 */
306     b = II (b, c, d, a, x[13],  21, 0x4e0811a1); /* 60 */
307     a = II (a, b, c, d, x[ 4],   6, 0xf7537e82); /* 61 */
308     d = II (d, a, b, c, x[11],  10, 0xbd3af235); /* 62 */
309     c = II (c, d, a, b, x[ 2],  15, 0x2ad7d2bb); /* 63 */
310     b = II (b, c, d, a, x[ 9],  21, 0xeb86d391); /* 64 */
311 
312     state.state[0] += a;
313     state.state[1] += b;
314     state.state[2] += c;
315     state.state[3] += d;
316   }
317 
318   /**
319    * Updates hash with the bytebuffer given (using at maximum length bytes from
320    * that buffer)
321    *
322    * @param state  Which state is updated
323    * @param buffer  Array of bytes to be hashed
324    * @param offset  Offset to buffer array
325    * @param length  Use at maximum `length' bytes (absolute
326    *      maximum is buffer.length)
327    */
328   public void Update (MD5State stat, byte buffer[], int offset, int length) {
329     int  index, partlen, i, start;
330 
331 /*    System.out.print("Offset = " + offset + "\tLength = " + length + "\t");
332     System.out.print("Buffer = ");
333     for (i = 0; i < buffer.length; i++)
334   System.out.print((int) (buffer[i] & 0xff) + " ");
335     System.out.print("\n");*/
336 
337     finals = null;
338 
339     /* Length can be told to be shorter, but not inter */
340     if ((length - offset)> buffer.length)
341       length = buffer.length - offset;
342 
343     /* compute number of bytes mod 64 */
344     index = (int) (stat.count[0] >>> 3) & 0x3f;
345 
346     if ((stat.count[0] += (length << 3)) <
347   (length << 3))
348       stat.count[1]++;
349 
350     stat.count[1] += length >>> 29;
351 
352     partlen = 64 - index;
353 
354     if (length >= partlen) {
355       for (i = 0; i < partlen; i++)
356   stat.buffer[i + index] = buffer[i + offset];
357 
358       Transform(stat, stat.buffer, 0);
359 
360       for (i = partlen; (i + 63) < length; i+= 64)
361   Transform(stat, buffer, i);
362 
363       index = 0;
364     } else
365       i = 0;
366 
367     /* buffer remaining input */
368     if (i < length) {
369       start = i;
370       for (; i < length; i++)
371   stat.buffer[index + i - start] = buffer[i + offset];
372     }
373   }
374 
375   /*
376    * Update()s for other datatypes than byte[] also. Update(byte[], int)
377    * is only the main driver.
378    */
379 
380   /**
381    * Plain update, updates this object
382    */
383 
384   public void Update (byte buffer[], int offset, int length) {
385       Update(this.state, buffer, offset, length);
386   }
387 
388   public void Update (byte buffer[], int length) {
389       Update(this.state, buffer, 0, length);
390   }
391 
392   /**
393    * Updates hash with given array of bytes
394    *
395    * @param buffer  Array of bytes to use for updating the hash
396    */
397   public void Update (byte buffer[]) {
398       Update(buffer, 0, buffer.length);
399   }
400 
401   /**
402    * Updates hash with a single byte
403    *
404    * @param b    Single byte to update the hash
405    */
406   public void Update (byte b) {
407     byte buffer[] = new byte[1];
408     buffer[0] = b;
409 
410     Update(buffer, 1);
411   }
412 
413   /**
414    * Update buffer with given string.
415    *
416    * @param s    String to be update to hash (is used as
417    *             s.getBytes())
418    */
419   public void Update (String s) {
420     byte  chars[];
421 
422     chars = new byte[s.length()];
423 // tobias    
424     chars = s.getBytes();
425 //    s.getBytes(0, s.length(), chars, 0);
426 
427     Update(chars, chars.length);
428   }
429 
430   /**
431    * Update buffer with a single integer (only & 0xff part is used,
432    * as a byte)
433    *
434    * @param i    Integer value, which is then converted to
435    *      byte as i & 0xff
436    */
437 
438   public void Update (int i) {
439       Update((byte) (i & 0xff));
440   }
441 
442   private byte[] Encode (int input[], int len) {
443     int    i, j;
444     byte  out[];
445 
446     out = new byte[len];
447 
448     for (i = j = 0; j  < len; i++, j += 4) {
449       out[j] = (byte) (input[i] & 0xff);
450       out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
451       out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
452       out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
453     }
454 
455     return out;
456   }
457 
458   /**
459    * Returns array of bytes (16 bytes) representing hash as of the
460    * current state of this object. Note: getting a hash does not
461    * invalidate the hash object, it only creates a copy of the real
462    * state which is finalized.
463    *
464    * @return  Array of 16 bytes, the hash of all updated bytes
465    */
466   public synchronized byte[] Final () {
467     byte  bits[];
468     int    index, padlen;
469     MD5State  fin;
470 
471     if (finals == null) {
472       fin = new MD5State(state);
473 
474       bits = Encode(fin.count, 8);
475 
476       index = (int) ((fin.count[0] >>> 3) & 0x3f);
477       padlen = (index < 56) ? (56 - index) : (120 - index);
478 
479       Update(fin, padding, 0, padlen);
480       /**/
481       Update(fin, bits, 0, 8);
482 
483       /* Update() sets finalds to null */
484       finals = fin;
485     }
486 
487     return Encode(finals.state, 16);
488   }
489 
490   /**
491    * Turns array of bytes into string representing each byte as
492    * unsigned hex number.
493    *
494    * @param hash  Array of bytes to convert to hex-string
495    * @return  Generated hex string
496    */
497   public static String asHex (byte hash[]) {
498     StringBuffer buf = new StringBuffer(hash.length * 2);
499     int i;
500 
501     for (i = 0; i < hash.length; i++) {
502       if (((int) hash[i] & 0xff) < 0x10)
503   buf.append("0");
504 
505       buf.append(Long.toString((int) hash[i] & 0xff, 16));
506     }
507 
508     return buf.toString();
509   }
510 
511   /**
512    * Returns 32-character hex representation of this objects hash
513    *
514    * @return String of this object's hash
515    */
516   public String asHex () {
517     return asHex(this.Final());
518   }
519 }