tanjent@gmail.com | f3b7897 | 2012-03-01 03:38:55 +0000 | [diff] [blame] | 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 | } |