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

Quick Search    Search Deep

Source code: com/ssttr/crypto/MessageDigest.java


1   /*
2    * @(#)MessageDigest.java  1.7 95/08/15
3    *
4    * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
5    *
6    * Permission to use, copy, modify, and distribute this software
7    * and its documentation for NON-COMMERCIAL purposes and without
8    * fee is hereby granted provided that this copyright notice
9    * appears in all copies. Please refer to the file "copyright.html"
10   * for further important copyright and licensing information.
11   *
12   * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
13   * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14   * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15   * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
16   * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
17   * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
18   *
19   * Updated to JDK 1.0.2 levels by Chuck McManis
20   * 
21   * This file was obtained from: http://www.mcmanis.com/~cmcmanis/java/src/util/crypt/MessageDigest.java
22   * More information can be found here: http://www.mcmanis.com/~cmcmanis/java/
23   */
24  
25  package com.ssttr.crypto;
26  
27  import java.util.*;
28  import java.io.ByteArrayOutputStream;
29  import java.io.PrintStream;
30  import java.io.InputStream;
31  
32  
33  /**
34   * The MessageDigest class defines a general class for computing digest
35   * functions. It is defined as an abstract class that is subclassed by
36   * message digest algorithms. In this way the PKCS classes can be built
37   * to take a MessageDigest object without needing to know what 'kind'
38   * of message digest they are computing.
39   *
40   * This class defines the standard functions that all message digest
41   * algorithms share, and ways to put all Java fundamental types into
42   * the digest. It does not define methods for digestifying either
43   * arbitrary objects or arrays of objects however.
44   *
45   * @version   5 Oct 1996, 1.8
46   * @author   Chuck McManis
47   */
48  public abstract class MessageDigest
49  {
50  
51      /** the actual digest bits. */
52      public byte digestBits[];
53  
54      /** status of the digest */
55      public boolean digestValid;
56  
57      /**
58       * This function is used to initialize any internal digest
59       * variables or parameters.
60       */
61      public abstract void init();
62  
63      /**
64       * The basic unit of digestifying is the byte. This method is
65       * defined by the particular algorithim's subclass for that
66       * algorithim. Subsequent versions of this method defined here
67       * decompose the basic type into bytes and call this function.
68       * If special processing is needed for a particular type your
69       * subclass should override the method for that type.
70       */
71      public abstract void update(byte aValue);
72  
73      /**
74       * Add a boolean to the digest.
75       */
76      public synchronized void update(boolean aValue) {
77          byte  b;
78  
79          if (aValue)
80              b = 1;
81          else
82              b = 0;
83          update(b);
84      }
85  
86      /**
87       * Add a short value to the digest.
88       */
89      public synchronized void update(short aValue) {
90          byte  b1, b2;
91  
92          b1 = (byte)((aValue >>> 8) & 0xff);
93          b2 = (byte)(aValue & 0xff);
94          update(b1);
95          update(b2);
96      }
97  
98      /**
99       * Add an integer value to the digest.
100      */
101     public synchronized void update(int aValue) {
102         byte  b;
103 
104         for (int i = 3; i >= 0; i--) {
105             b = (byte)((aValue >>> (i * 8)) & 0xff);
106             update(b);
107         }
108     }
109 
110     /**
111      * Add a long to the digest.
112      */
113     public synchronized void update(long aValue) {
114         byte  b;
115 
116       for (int i = 7; i >= 0; i--) {
117           b = (byte)((aValue >>> (i * 8)) & 0xff);
118           update(b);
119       }
120     }
121 
122     /**
123      * Add specific bytes to the digest.
124      */
125     public synchronized void update(byte input[], int offset, int len) {
126         for (int i = 0; i < len; i++) {
127             update(input[i+offset]);
128         }
129     }
130 
131     /**
132      * Add an array of bytes to the digest.
133      */
134     public synchronized void update(byte input[]) {
135         update(input, 0, input.length);
136     }
137 
138     /**
139      * Add an array of shorts to the digest.
140      */
141     public synchronized void update(short input[]) {
142       for (int i = 0; i < input.length; i++) {
143           update(input[i]);
144       }
145     }
146 
147     /**
148      * Add an array of integers to the digest.
149      */
150     public synchronized void update(int input[]) {
151       for (int i = 0; i < input.length; i++) {
152           update(input[i]);
153       }
154     }
155 
156     /**
157      * Add an array of longs to the digest.
158      */
159     public synchronized void update(long input[]) {
160       for (int i = 0; i < input.length; i++) {
161           update(input[i]);
162       }
163     }
164 
165     /**
166      * Add the bytes in the String 'input' to the current digest.
167      * Note that the string characters are treated as unicode chars
168      * of 16 bits each. To digestify ISO-Latin1 strings (ASCII) use
169      * the updateASCII() method.
170      */
171     public void update(String input) {
172       int  i, len;
173       short  x;
174 
175       len = input.length();
176       for (i = 0; i < len; i++) {
177           x = (short) input.charAt(i);
178           update(x);
179       }
180     }
181 
182     /**
183      * Treat the string as a sequence of ISO-Latin1 (8 bit) characters.
184      */
185     public void updateASCII(String input) {
186       int  i, len;
187       byte  x;
188 
189       len = input.length();
190       for (i = 0; i < len; i++) {
191           x = (byte) (input.charAt(i) & 0xff);
192           update(x);
193       }
194     }
195 
196     /**
197      * Read a stream and update a digest until the
198      * stream sends an EOF.
199      */
200     public void update(InputStream in) {
201       byte  b;
202 
203         try {
204           while ((b = (byte) in.read()) != -1)
205               update(b);
206       } catch (Exception e) { }
207     }
208 
209     /**
210      * Perform the final computations and cleanup.
211      */
212     public abstract void finish();
213 
214     /**
215      * Complete digest computation on an array of bytes.
216      */
217     public void computeDigest(byte source[]) {
218       init();
219       update(source);
220       finish();
221     }
222 
223     public void computeDigest(InputStream in) {
224       init();
225       update(in);
226       finish();
227     }
228 
229     /**
230      * helper function that prints unsigned two character hex digits.
231      */
232     private void hexDigit(PrintStream p, byte x) {
233       char c;
234 
235       c = (char) ((x >> 4) & 0xf);
236       if (c > 9)
237         c = (char) ((c - 10) + 'a');
238       else
239         c = (char) (c + '0');
240       p.write(c);
241       c = (char) (x & 0xf);
242       if (c > 9)
243         c = (char)((c-10) + 'a');
244       else
245         c = (char)(c + '0');
246       p.write(c);
247     }
248 
249     /**
250      * Return a string representation of this object.
251      */
252     public String toString() {
253       ByteArrayOutputStream ou = new ByteArrayOutputStream();
254       PrintStream p = new PrintStream(ou);
255 
256       p.print(this.getClass().getName()+" Message Digest ");
257       if (digestValid) {
258           p.print("<");
259           for(int i = 0; i < digestBits.length; i++)
260                hexDigit(p, digestBits[i]);
261           p.print(">");
262       } else {
263           p.print("<incomplete>");
264       }
265       p.println();
266       return (ou.toString());
267     }
268     
269     public String getDigest()
270     {
271       if (digestValid) {
272             StringBuffer b = new StringBuffer();
273           for(int i = 0; i < digestBits.length; i++)
274                b.append( (char)digestBits[i] );
275             return b.toString();
276       }
277         else
278         {
279           return null;
280       }
281     }
282     
283     public byte[] getDigestBytes()
284     {
285         if(digestValid) {
286             return digestBits;
287         }
288         else
289         {
290             return null;
291         }
292     }
293     
294     public String getDigestHex()
295     {
296       ByteArrayOutputStream ou = new ByteArrayOutputStream();
297       PrintStream p = new PrintStream(ou);
298 
299       if (digestValid) {
300           for(int i = 0; i < digestBits.length; i++)
301                hexDigit(p, digestBits[i]);
302       } else {
303           return null;
304       }
305       return (ou.toString());
306     }
307 
308     /**
309      * Compare two digests for equality. Simple byte compare.
310      */
311     public static boolean isEqual(byte digesta[], byte digestb[]) {
312       int  i;
313 
314       if (digesta.length != digestb.length)
315           return (false);
316 
317       for (i = 0; i < digesta.length; i++) {
318           if (digesta[i] != digestb[i]) {
319         return (false);
320           }
321       }
322       return (true);
323     }
324 
325     /**
326      * Non static version that compares this digest to one passed.
327      */
328     public boolean isEqual(byte otherDigest[]) {
329       return (MessageDigest.isEqual(digestBits, otherDigest));
330     }
331 
332     /**
333      * Return a string that represents the algorithim of this
334      * message digest.
335      */
336     public abstract String getAlg();
337 
338     static byte testdata[];
339 
340     public static void benchmark(MessageDigest md) {
341         Random rnd = new Random(); // use random data
342         testdata = new byte[16384];
343         long times[] = new long[14];
344         double rates[] = new double[14];
345 
346         for (int i = 0; i < testdata.length; i++) {
347             testdata[i] = (byte) (rnd.nextInt() >>> 8);
348         }
349         System.out.println("Benchmarking "+md.getAlg());
350         System.out.println("Bytes   Time (mS)   Rate (Bytes/Sec)");
351         for (int i = 1; i < 10; i++) {
352             long t1 = System.currentTimeMillis();
353             md.init();
354             for (int k = 0; k < i; k++)
355                 md.update(testdata);
356             md.finish();
357             times[i] = System.currentTimeMillis() - t1;
358             rates[i] = ((double) (i*testdata.length) * 1000.0)/ (double) times[i];
359             System.out.println((i*testdata.length)+"\t"+times[i]+"\t"+rates[i]);
360         }
361         System.out.println("Done.");
362     }
363 
364 }