blob: 63f00f8ad259ac335cb7313722ee40fcfde60977 [file] [log] [blame]
tanjent@gmail.comf3b78972012-03-01 03:38:55 +00001// 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
28uint32_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
69void lookup3_test ( const void * key, int len, uint32_t seed, void * out )
70{
71 *(uint32_t*)out = lookup3(key,len,seed);
72}