Home | History | Annotate | Download | only in src
      1 // lookup3 by Bob Jekins, code is public domain.
      2 
      3 #include "Platform.h"
      4 
      5 #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
      6 
      7 #define mix(a,b,c) \
      8 { \
      9   a -= c;  a ^= rot(c, 4);  c += b; \
     10   b -= a;  b ^= rot(a, 6);  a += c; \
     11   c -= b;  c ^= rot(b, 8);  b += a; \
     12   a -= c;  a ^= rot(c,16);  c += b; \
     13   b -= a;  b ^= rot(a,19);  a += c; \
     14   c -= b;  c ^= rot(b, 4);  b += a; \
     15 }
     16 
     17 #define final(a,b,c) \
     18 { \
     19   c ^= b; c -= rot(b,14); \
     20   a ^= c; a -= rot(c,11); \
     21   b ^= a; b -= rot(a,25); \
     22   c ^= b; c -= rot(b,16); \
     23   a ^= c; a -= rot(c,4);  \
     24   b ^= a; b -= rot(a,14); \
     25   c ^= b; c -= rot(b,24); \
     26 }
     27 
     28 uint32_t lookup3 ( const void * key, int length, uint32_t initval )
     29 {
     30   uint32_t a,b,c;                                          /* internal state */
     31 
     32   a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
     33 
     34   const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
     35 
     36   /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
     37   while (length > 12)
     38   {
     39     a += k[0];
     40     b += k[1];
     41     c += k[2];
     42     mix(a,b,c);
     43     length -= 12;
     44     k += 3;
     45   }
     46 
     47   switch(length)
     48   {
     49     case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
     50     case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
     51     case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
     52     case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
     53     case 8 : b+=k[1]; a+=k[0]; break;
     54     case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
     55     case 6 : b+=k[1]&0xffff; a+=k[0]; break;
     56     case 5 : b+=k[1]&0xff; a+=k[0]; break;
     57     case 4 : a+=k[0]; break;
     58     case 3 : a+=k[0]&0xffffff; break;
     59     case 2 : a+=k[0]&0xffff; break;
     60     case 1 : a+=k[0]&0xff; break;
     61     case 0 : { return c; }              /* zero length strings require no mixing */
     62   }
     63 
     64   final(a,b,c);
     65 
     66   return c;
     67 }
     68 
     69 void lookup3_test ( const void * key, int len, uint32_t seed, void * out )
     70 {
     71   *(uint32_t*)out = lookup3(key,len,seed);
     72 }
     73