00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package Acme.Crypto;
00030
00031 import java.io.*;
00032
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 public abstract class Hash extends CryptoUtils
00046 {
00047
00049 protected int hashSize;
00050
00052 protected byte[] hashBytes;
00053
00055
00056
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
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
00085
00086
00087
00088
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
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
00194
00196
00197
00198
00199
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
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 }