Hash.java

00001 // Hash - a hash-function template
00002 //
00003 // Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
00004 //
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions
00007 // are met:
00008 // 1. Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 // 2. Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //
00014 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00015 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00017 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00018 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00019 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00020 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00021 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00022 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00023 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00024 // SUCH DAMAGE.
00025 //
00026 // Visit the ACME Labs Java page for up-to-date versions of this and other
00027 // fine Java utilities: http://www.acme.com/java/
00028 
00029 package Acme.Crypto;
00030 
00031 import java.io.*;
00032 
00034 // <P>
00035 // Hash functions are also known as message digests or checksums.
00036 // The idea is to reduce an arbitrary-length stream of bytes down
00037 // to a fixed size, useful for comparisons, security, whatever.
00038 // <P>
00039 // <A HREF="/resources/classes/Acme/Crypto/Hash.java">Fetch the software.</A><BR>
00040 // <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
00041 // <P>
00042 // @see StreamCipher
00043 // @see BlockCipher
00044 
00045 public abstract class Hash extends CryptoUtils
00046     {
00047 
00049     protected int hashSize;
00050 
00052     protected byte[] hashBytes;
00053 
00055     // We can't call it here because it would get called before the
00056     // sub-class's variable initializations.
00057     public Hash( int hashSize )
00058         {
00059         this.hashSize = hashSize;
00060         hashBytes = new byte[hashSize];
00061         }
00062 
00064     public int hashSize()
00065         {
00066         return hashSize;
00067         }
00068 
00070     public abstract void reset();
00071 
00073     public abstract void add( byte b );
00074 
00076     // repeatedly.  Can be overridden for efficiency.
00077     public void add( byte[] data, int off, int len )
00078         {
00079         for ( int i = off; i < off + len; ++i )
00080             add( data[i] );
00081         }
00082 
00084     // before returning the bytes, and by other routines such as equals() and
00085     // toString() before looking at the bytes.  The default implementation does
00086     // nothing, but if a subclass wants to store the hash in some
00087     // form other than a byte array, it should override this routine
00088     // and have if convert the hash to bytes and store in hashBytes.
00089     protected void prepare()
00090         {
00091         }
00092 
00094     public byte[] get()
00095         {
00096         prepare();
00097         byte[] hb = new byte[hashSize];
00098         System.arraycopy( hashBytes, 0, hb, 0, hashSize );
00099         return hb;
00100         }
00101 
00102 
00103     // Utility add routines for other types of input.
00104 
00106     public void add( String str )
00107         {
00108         int len = str.length();
00109         char[] data = new char[len];
00110         str.getChars( 0, len, data, 0 );
00111         for ( int i = 0; i < len; ++i )
00112             add( data[i] );
00113         }
00114 
00116     public void addASCII( String str )
00117         {
00118         int len = str.length();
00119         byte[] data = str.getBytes();
00120         add( data, 0, len );
00121         }
00122 
00124     public void add( byte[] data )
00125         {
00126         add( data, 0, data.length );
00127         }
00128 
00130     public void add( boolean b )
00131         {
00132         if ( b )
00133             add( (byte) 1 );
00134         else
00135             add( (byte) 0 );
00136         }
00137 
00139     public void add( char c )
00140         {
00141         add( (byte) ( c >>> 8 ) );
00142         add( (byte) c );
00143         }
00144 
00146     public void add( short s )
00147         {
00148         add( (byte) ( s >>> 8 ) );
00149         add( (byte) s );
00150         }
00151 
00153     public void add( int i )
00154         {
00155         add( (byte) ( i >>> 24 ) );
00156         add( (byte) ( i >>> 16 ) );
00157         add( (byte) ( i >>>  8 ) );
00158         add( (byte) i );
00159         }
00160 
00162     public void add( long l )
00163         {
00164         add( (byte) ( l >>> 56 ) );
00165         add( (byte) ( l >>> 48 ) );
00166         add( (byte) ( l >>> 40 ) );
00167         add( (byte) ( l >>> 32 ) );
00168         add( (byte) ( l >>> 24 ) );
00169         add( (byte) ( l >>> 16 ) );
00170         add( (byte) ( l >>>  8 ) );
00171         add( (byte) l );
00172         }
00173 
00175     public void add( float f )
00176         {
00177         add( Float.floatToIntBits( f ) );
00178         }
00179 
00181     public void add( double d )
00182         {
00183         add( Double.doubleToLongBits( d ) );
00184         }
00185 
00187     public void add( Object o )
00188         {
00189         add( o.toString() );
00190         }
00191 
00192 
00193     // Other utility routines.
00194 
00196     // Call like so:
00197     // <BLOCKQUOTE>
00198     // byte[] hash = SomeHash.hashStr( str, new SomeHash() );
00199     // </BLOCKQUOTE>
00200     public static byte[] hashStr( String str, Hash hash )
00201         {
00202         hash.add( str );
00203         return hash.get();
00204         }
00205 
00206 
00208     public boolean equals( Hash otherHash )
00209         {
00210         if ( otherHash.hashSize != hashSize )
00211             return false;
00212         otherHash.prepare();
00213         prepare();
00214         for ( int i = 0; i < hashSize; ++i )
00215             if ( otherHash.hashBytes[i] != hashBytes[i] )
00216                 return false;
00217         return true;
00218         }
00219     
00221     // A hash of a Hash.
00222     public int hashCode()
00223         {
00224         prepare();
00225         int code = 0, shift = 0;
00226         for ( int i = 0; i < hashSize; ++i )
00227             {
00228             code ^= hashBytes[i] << shift;
00229             shift = ( shift + 8 ) % 32;
00230             }
00231         return code;
00232         }
00233     
00235     public String toString()
00236         {
00237         prepare();
00238         return toStringBlock( hashBytes, 0, hashSize );
00239         }
00240 
00241     }

Generated on Mon Dec 4 11:03:27 2006 for OpenMobileIS by  doxygen 1.5.1-p1