Simple data structures / objects in plain C Snapshot
hashfunction.c
Go to the documentation of this file.
00001 /* Copyright (c) Michael Moser (2011) . 3-clause BSD License applies */
00002 
00003 #include "hashfunction.h"
00004 
00005 
00006 
00007 HASH_VALUE      HASHFUNCTION_sample_hash_func(void * keydata, ssize_t key_length)
00008 {
00009         unsigned char * key = (unsigned char *) keydata;
00010         HASH_VALUE hash_val = 0;
00011                 
00012         if (key_length != -1 ) {
00013                 do {
00014                         hash_val = (hash_val<<5) + hash_val + *key++;   
00015                         key_length --;
00016                 } while (key_length != 0);
00017                 return hash_val;
00018         } else {
00019                 
00020 
00021                 while (*key  ) {
00022                         hash_val = (hash_val<<5) + hash_val + *key++;
00023 
00024                 }
00025                 return hash_val;
00026         }
00027 
00028 }
00029 
00030 HASH_VALUE      HASHFUNCTION_PJW(void * keydata, ssize_t key_length)
00031 {
00032         unsigned char * key = (unsigned char *) keydata;
00033         HASH_VALUE g = 0, hash_val = 0;
00034 
00035         if (key_length != -1) {
00036                 do {
00037                         hash_val = (hash_val<<4) + hash_val + *key++;   
00038                         g = hash_val & 0xF0000000;
00039                         if (g) {
00040                                 hash_val = hash_val ^ ( g >> 24);
00041                                 hash_val = hash_val ^ g;
00042                         }
00043                         key_length --;
00044                 } while (key_length != 0);
00045 
00046                 return hash_val;
00047         } else {
00048                 
00049 
00050                 while (*key ) {
00051                         hash_val = (hash_val<<4) + hash_val + *key++;   
00052                         g = hash_val & 0xF0000000;
00053                         if (g) {
00054                                 hash_val = hash_val ^ ( g >> 24);
00055                                 hash_val = hash_val ^ g;
00056                         }
00057                 }
00058                 return hash_val;
00059         }
00060 }
00061 
00062 HASH_VALUE HASHFUNCTION_rotating(void * keydata, ssize_t key_length)
00063 {
00064   HASH_VALUE hash;
00065   unsigned char * key = (unsigned char *) keydata;
00066   ssize_t i;
00067 
00068   if (key_length != -1) {
00069                 for (hash = key_length, i=0; i<key_length; ++i) {
00070                         hash = (hash<<4)^(hash>>28) ^ key[i];
00071                 }
00072                 return hash;
00073   } else {
00074                 
00075 
00076                 for (hash = ((size_t)*key) << 16; *key  ; ++key) {
00077                         hash = (hash<<4)^(hash>>28) ^ (*key);
00078                 }
00079                 return hash;
00080   }
00081 }
00082 
00083 HASH_VALUE HASHFUNCTION_shift_and_xor(void * keydata, ssize_t key_length)
00084 {
00085   HASH_VALUE hash;
00086   unsigned char * key = (unsigned char *) keydata;
00087   ssize_t i;
00088 
00089   if (key_length != -1) {
00090                 for (hash = key_length, i=0; i<key_length; ++i) {
00091                         hash ^= (hash<<5) + (hash>>2)  + key[i];
00092                 }
00093                 return hash;
00094   } else {
00095                 
00096 
00097                 for (hash = ((size_t)*key) << 16; *key ; ++key) {
00098                         hash ^= (hash<<5) + (hash>>2)  + (*key);
00099                 }
00100                 return hash;
00101   }
00102 }
00103 
00104 
00105 HASH_VALUE HASHFUNCTION_Fowler_Noll_Vo(void * keydata, ssize_t key_length)
00106 {
00107   HASH_VALUE hash = 2166136261U;
00108   unsigned char * key = (unsigned char *) keydata;
00109   ssize_t i;
00110 
00111   if (key_length != -1) {
00112                 for (hash = 0, i=0; i<key_length; ++i) {
00113                         hash = ( hash * 16777619U ) ^ key[i];
00114                 }
00115                 return hash;
00116   } else {
00117                 
00118 
00119                 for (hash = 0; *key ; ++key) {
00120                         hash = ( hash * 16777619U ) ^ (*key);
00121                 }
00122                 return hash;
00123   }
00124 }
00125 
00126 HASH_VALUE HASHFUNCTION_Bob_Jenkins_one_at_a_time(void * keydata, ssize_t key_length)
00127 {
00128   HASH_VALUE h = 2166136261U;
00129   unsigned char * key = (unsigned char *) keydata;
00130   ssize_t i;
00131 
00132 
00133   if (key_length != -1) {
00134         
00135         for ( i = 0; i < key_length; i++ ) {
00136                 h += key[i];
00137                 h += ( h << 10 );
00138                 h ^= ( h >> 6 );
00139         }
00140 
00141         h += ( h << 3 );
00142         h ^= ( h >> 11 );
00143         h += ( h << 15 );
00144 
00145         return h;
00146 
00147   } else {
00148         
00149 
00150         for ( ; *key ; ++key ) {
00151                 h += *key;
00152                 h += ( h << 10 );
00153                 h ^= ( h >> 6 );
00154         }
00155 
00156         h += ( h << 3 );
00157         h ^= ( h >> 11 );
00158         h += ( h << 15 );
00159 
00160         return h;
00161   }
00162 }
00163 
00164 HASH_VALUE HASHFUNCTION_ELF(void * keydata, ssize_t key_length)
00165 {
00166   HASH_VALUE h = 2166136261U,g;
00167   unsigned char * key = (unsigned char *) keydata;
00168   ssize_t i;
00169 
00170   if (key_length != -1) {
00171         
00172         for ( i = 0; i < key_length; i++ ) {
00173                 h = ( h << 4 ) + key[i];
00174                 g = h & 0xf0000000L;
00175 
00176                 if ( g != 0 )
00177                         h ^= g >> 24;
00178                 
00179                 h &= ~g;
00180         }
00181         return h;
00182   
00183   } else {
00184                 
00185 
00186         for ( ; *key ;key++ ) {
00187                 h = ( h << 4 ) + *key;
00188                 g = h & 0xf0000000L;
00189 
00190                 if ( g != 0 )
00191                         h ^= g >> 24;
00192                 
00193                 h &= ~g;
00194 
00195                 return h;
00196         }
00197 
00198         return h;
00199   }
00200 }
00201 
00202  #define hashsize(n) ( 1U << (n) )
00203  #define hashmask(n) ( hashsize ( n ) - 1 )
00204  
00205  #define mix(a,b,c) \
00206  { \
00207    a -= b; a -= c; a ^= ( c >> 13 ); \
00208    b -= c; b -= a; b ^= ( a << 8 ); \
00209    c -= a; c -= b; c ^= ( b >> 13 ); \
00210    a -= b; a -= c; a ^= ( c >> 12 ); \
00211    b -= c; b -= a; b ^= ( a << 16 ); \
00212    c -= a; c -= b; c ^= ( b >> 5 ); \
00213    a -= b; a -= c; a ^= ( c >> 3 ); \
00214    b -= c; b -= a; b ^= ( a << 10 ); \
00215    c -= a; c -= b; c ^= ( b >> 15 ); \
00216  }
00217  
00218 #define BJ_INIT_VAL 2166136261U
00219 
00220 HASH_VALUE HASHFUNCTION_Bob_Jenkins(void * keydata, ssize_t length)
00221 {
00222     unsigned char *k = keydata;
00223     unsigned a, b;
00224     unsigned c = BJ_INIT_VAL;
00225     unsigned len = length;
00226  
00227     a = b = 0x9e3779b9;
00228 
00229         if (length != -1) {
00230  
00231                 while ( len >= 12 ) {
00232                    a += ( k[0] + ( (unsigned)k[1] << 8 ) 
00233                          + ( (unsigned)k[2] << 16 )
00234                          + ( (unsigned)k[3] << 24 ) );
00235                    b += ( k[4] + ( (unsigned)k[5] << 8 ) 
00236                          + ( (unsigned)k[6] << 16 )
00237                          + ( (unsigned)k[7] << 24 ) );
00238                    c += ( k[8] + ( (unsigned)k[9] << 8 ) 
00239                          + ( (unsigned)k[10] << 16 )
00240                          + ( (unsigned)k[11] << 24 ) );
00241  
00242                    mix ( a, b, c );
00243  
00244                    k += 12;
00245                    len -= 12;
00246                 }
00247         } else {
00248                 size_t pos_k = 0;
00249                 unsigned char *next_k;
00250                         
00251 
00252                 length = 0;
00253 
00254                 while(1) {
00255 
00256                         for(pos_k = 0, next_k = (unsigned char *) k;
00257                                 *next_k && pos_k<12 ;
00258                                 pos_k++, next_k++);
00259 
00260                         length += pos_k;
00261                                 
00262                         if (pos_k < 12) {
00263                                 len = pos_k;
00264                                 break;
00265                         }
00266         
00267                         a += ( k[0] + ( (unsigned)k[1] << 8 ) 
00268                           + ( (unsigned)k[2] << 16 )
00269                           + ( (unsigned)k[3] << 24 ) );
00270                         b += ( k[4] + ( (unsigned)k[5] << 8 ) 
00271                           + ( (unsigned)k[6] << 16 )
00272                           + ( (unsigned)k[7] << 24 ) );
00273                         c += ( k[8] + ( (unsigned)k[9] << 8 ) 
00274                           + ( (unsigned)k[10] << 16 )
00275                           + ( (unsigned)k[11] << 24 ) );
00276 
00277                         mix ( a, b, c );
00278 
00279                         k += 12;
00280 
00281                 }
00282         }
00283  
00284     c += length;
00285  
00286     switch ( len ) {
00287     case 11: c += ( (unsigned)k[10] << 24 );
00288     case 10: c += ( (unsigned)k[9] << 16 );
00289     case 9 : c += ( (unsigned)k[8] << 8 );
00290     /* First byte of c reserved for length */
00291     case 8 : b += ( (unsigned)k[7] << 24 );
00292     case 7 : b += ( (unsigned)k[6] << 16 );
00293     case 6 : b += ( (unsigned)k[5] << 8 );
00294     case 5 : b += k[4];
00295     case 4 : a += ( (unsigned)k[3] << 24 );
00296     case 3 : a += ( (unsigned)k[2] << 16 );
00297     case 2 : a += ( (unsigned)k[1] << 8 );
00298     case 1 : a += k[0];
00299     }
00300  
00301     mix ( a, b, c );
00302  
00303     return c;
00304 }