1080 lines
35 KiB
C
1080 lines
35 KiB
C
// code taken more-or-less from Paul Hsieh's tests
|
|
|
|
#include "Hasher.H"
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
|
|
#ifndef CLOCKS_PER_SEC
|
|
# ifdef CLK_TCK
|
|
# define CLOCKS_PER_SEC (CLK_TCK)
|
|
# endif
|
|
#endif
|
|
|
|
#undef mix
|
|
#undef rot
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
lookup3.c, by Bob Jenkins, May 2006, Public Domain.
|
|
|
|
These are functions for producing 32-bit hashes for hash table lookup.
|
|
hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
|
|
are externally useful functions. Routines to test the hash are included
|
|
if SELF_TEST is defined. You can use this free for any purpose. It's in
|
|
the public domain. It has no warranty.
|
|
|
|
You probably want to use hashlittle(). hashlittle() and hashbig()
|
|
hash byte arrays. hashlittle() is is faster than hashbig() on
|
|
little-endian machines. Intel and AMD are little-endian machines.
|
|
On second thought, you probably want hashlittle2(), which is identical to
|
|
hashlittle() except it returns two 32-bit hashes for the price of one.
|
|
You could implement hashbig2() if you wanted but I haven't bothered here.
|
|
|
|
If you want to find a hash of, say, exactly 7 integers, do
|
|
a = i1; b = i2; c = i3;
|
|
mix(a,b,c);
|
|
a += i4; b += i5; c += i6;
|
|
mix(a,b,c);
|
|
a += i7;
|
|
final(a,b,c);
|
|
then use c as the hash value. If you have a variable length array of
|
|
4-byte integers to hash, use hashword(). If you have a byte array (like
|
|
a character string), use hashlittle(). If you have several byte arrays, or
|
|
a mix of things, see the comments above hashlittle().
|
|
|
|
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
|
|
then mix those integers. This is fast (you can do a lot more thorough
|
|
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
|
|
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <stdio.h> /* defines printf for tests */
|
|
#include <time.h> /* defines time_t for timings in the test */
|
|
#include <stdint.h> /* defines uint32_t etc */
|
|
#include <sys/param.h> /* attempt to define endianness */
|
|
#ifdef linux
|
|
# include <endian.h> /* attempt to define endianness */
|
|
#endif
|
|
|
|
/*
|
|
* My best guess at if you are big-endian or little-endian. This may
|
|
* need adjustment.
|
|
*/
|
|
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
|
|
__BYTE_ORDER == __LITTLE_ENDIAN) || \
|
|
(defined(i386) || defined(__i386__) || defined(__i486__) || \
|
|
defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
|
|
# define HASH_LITTLE_ENDIAN 1
|
|
# define HASH_BIG_ENDIAN 0
|
|
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
|
|
__BYTE_ORDER == __BIG_ENDIAN) || \
|
|
(defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
|
|
# define HASH_LITTLE_ENDIAN 0
|
|
# define HASH_BIG_ENDIAN 1
|
|
#else
|
|
# define HASH_LITTLE_ENDIAN 0
|
|
# define HASH_BIG_ENDIAN 0
|
|
#endif
|
|
|
|
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
mix -- mix 3 32-bit values reversibly.
|
|
|
|
This is reversible, so any information in (a,b,c) before mix() is
|
|
still in (a,b,c) after mix().
|
|
|
|
If four pairs of (a,b,c) inputs are run through mix(), or through
|
|
mix() in reverse, there are at least 32 bits of the output that
|
|
are sometimes the same for one pair and different for another pair.
|
|
This was tested for:
|
|
* pairs that differed by one bit, by two bits, in any combination
|
|
of top bits of (a,b,c), or in any combination of bottom bits of
|
|
(a,b,c).
|
|
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
|
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
|
is commonly produced by subtraction) look like a single 1-bit
|
|
difference.
|
|
* the base values were pseudorandom, all zero but one bit set, or
|
|
all zero plus a counter that starts at zero.
|
|
|
|
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
|
|
satisfy this are
|
|
4 6 8 16 19 4
|
|
9 15 3 18 27 15
|
|
14 9 3 7 17 3
|
|
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
|
|
for "differ" defined as + with a one-bit base and a two-bit delta. I
|
|
used http://burtleburtle.net/bob/hash/avalanche.html to choose
|
|
the operations, constants, and arrangements of the variables.
|
|
|
|
This does not achieve avalanche. There are input bits of (a,b,c)
|
|
that fail to affect some output bits of (a,b,c), especially of a. The
|
|
most thoroughly mixed value is c, but it doesn't really even achieve
|
|
avalanche in c.
|
|
|
|
This allows some parallelism. Read-after-writes are good at doubling
|
|
the number of bits affected, so the goal of mixing pulls in the opposite
|
|
direction as the goal of parallelism. I did what I could. Rotates
|
|
seem to cost as much as shifts on every machine I could lay my hands
|
|
on, and rotates are much kinder to the top and bottom bits, so I used
|
|
rotates.
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
#define mix(a,b,c) \
|
|
{ \
|
|
a -= c; a ^= rot(c, 4); c += b; \
|
|
b -= a; b ^= rot(a, 6); a += c; \
|
|
c -= b; c ^= rot(b, 8); b += a; \
|
|
a -= c; a ^= rot(c,16); c += b; \
|
|
b -= a; b ^= rot(a,19); a += c; \
|
|
c -= b; c ^= rot(b, 4); b += a; \
|
|
}
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
final -- final mixing of 3 32-bit values (a,b,c) into c
|
|
|
|
Pairs of (a,b,c) values differing in only a few bits will usually
|
|
produce values of c that look totally different. This was tested for
|
|
* pairs that differed by one bit, by two bits, in any combination
|
|
of top bits of (a,b,c), or in any combination of bottom bits of
|
|
(a,b,c).
|
|
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
|
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
|
is commonly produced by subtraction) look like a single 1-bit
|
|
difference.
|
|
* the base values were pseudorandom, all zero but one bit set, or
|
|
all zero plus a counter that starts at zero.
|
|
|
|
These constants passed:
|
|
14 11 25 16 4 14 24
|
|
12 14 25 16 4 14 24
|
|
and these came close:
|
|
4 8 15 26 3 22 24
|
|
10 8 15 26 3 22 24
|
|
11 8 15 26 3 22 24
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
#define final(a,b,c) \
|
|
{ \
|
|
c ^= b; c -= rot(b, 14); \
|
|
a ^= c; a -= rot(c, 11); \
|
|
b ^= a; b -= rot(a, 25); \
|
|
c ^= b; c -= rot(b, 16); \
|
|
a ^= c; a -= rot(c, 4); \
|
|
b ^= a; b -= rot(a, 14); \
|
|
c ^= b; c -= rot(b, 24); \
|
|
}
|
|
|
|
/*
|
|
--------------------------------------------------------------------
|
|
This works on all machines. To be useful, it requires
|
|
-- that the key be an array of uint32_t's, and
|
|
-- that the length be the number of uint32_t's in the key
|
|
|
|
The function hashword() is identical to hashlittle() on little-endian
|
|
machines, and identical to hashbig() on big-endian machines,
|
|
except that the length has to be measured in uint32_ts rather than in
|
|
bytes. hashlittle() is more complicated than hashword() only because
|
|
hashlittle() has to dance around fitting the key bytes into registers.
|
|
--------------------------------------------------------------------
|
|
*/
|
|
uint32_t hashword(
|
|
const uint32_t *k, /* the key, an array of uint32_t values */
|
|
size_t length, /* the length of the key, in uint32_ts */
|
|
uint32_t initval) /* the previous hash, or an arbitrary value */
|
|
{
|
|
uint32_t a,b,c;
|
|
|
|
/* Set up the internal state */
|
|
a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval;
|
|
|
|
/*------------------------------------------------- handle most of the key */
|
|
while (length > 3)
|
|
{
|
|
a += k[0];
|
|
b += k[1];
|
|
c += k[2];
|
|
mix(a,b,c);
|
|
length -= 3;
|
|
k += 3;
|
|
}
|
|
|
|
/*------------------------------------------- handle the last 3 uint32_t's */
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 3 : c+=k[2];
|
|
case 2 : b+=k[1];
|
|
case 1 : a+=k[0];
|
|
final(a,b,c);
|
|
case 0: /* case 0: nothing left to add */
|
|
break;
|
|
}
|
|
/*------------------------------------------------------ report the result */
|
|
return c;
|
|
}
|
|
|
|
|
|
/*
|
|
--------------------------------------------------------------------
|
|
hashword2() -- same as hashword(), but take two seeds and return two
|
|
32-bit values. pc and pb must both be nonnull, and *pc and *pb must
|
|
both be initialized with seeds. If you pass in (*pb)==0, the output
|
|
(*pc) will be the same as the return value from hashword().
|
|
--------------------------------------------------------------------
|
|
*/
|
|
void hashword2 (
|
|
const uint32_t *k, /* the key, an array of uint32_t values */
|
|
size_t length, /* the length of the key, in uint32_ts */
|
|
uint32_t *pc, /* IN: seed OUT: primary hash value */
|
|
uint32_t *pb) /* IN: more seed OUT: secondary hash value */
|
|
{
|
|
uint32_t a,b,c;
|
|
|
|
/* Set up the internal state */
|
|
a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc;
|
|
c += *pb;
|
|
|
|
/*------------------------------------------------- handle most of the key */
|
|
while (length > 3)
|
|
{
|
|
a += k[0];
|
|
b += k[1];
|
|
c += k[2];
|
|
mix(a,b,c);
|
|
length -= 3;
|
|
k += 3;
|
|
}
|
|
|
|
/*------------------------------------------- handle the last 3 uint32_t's */
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 3 : c+=k[2];
|
|
case 2 : b+=k[1];
|
|
case 1 : a+=k[0];
|
|
final(a,b,c);
|
|
case 0: /* case 0: nothing left to add */
|
|
break;
|
|
}
|
|
/*------------------------------------------------------ report the result */
|
|
*pc=c; *pb=b;
|
|
}
|
|
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
hashlittle() -- hash a variable-length key into a 32-bit value
|
|
k : the key (the unaligned variable-length array of bytes)
|
|
length : the length of the key, counting by bytes
|
|
initval : can be any 4-byte value
|
|
Returns a 32-bit value. Every bit of the key affects every bit of
|
|
the return value. Two keys differing by one or two bits will have
|
|
totally different hash values.
|
|
|
|
The best hash table sizes are powers of 2. There is no need to do
|
|
mod a prime (mod is sooo slow!). If you need less than 32 bits,
|
|
use a bitmask. For example, if you need only 10 bits, do
|
|
h = (h & hashmask(10));
|
|
In which case, the hash table should have hashsize(10) elements.
|
|
|
|
If you are hashing n strings (uint8_t **)k, do it like this:
|
|
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
|
|
|
|
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
|
|
code any way you wish, private, educational, or commercial. It's free.
|
|
|
|
Use for hash table lookup, or anything where one collision in 2^^32 is
|
|
acceptable. Do NOT use for cryptographic purposes.
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
|
|
uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
|
|
{
|
|
uint32_t a,b,c; /* internal state */
|
|
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
|
|
|
|
/* Set up the internal state */
|
|
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
|
|
|
u.ptr = key;
|
|
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
|
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
|
const uint8_t *k8;
|
|
|
|
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += k[0];
|
|
b += k[1];
|
|
c += k[2];
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 3;
|
|
}
|
|
|
|
/*----------------------------- handle the last (probably partial) block */
|
|
|
|
k8 = (const uint8_t *)k;
|
|
switch(length)
|
|
{
|
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
|
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
|
case 9 : c+=k8[8]; /* fall through */
|
|
case 8 : b+=k[1]; a+=k[0]; break;
|
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
|
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
|
case 5 : b+=k8[4]; /* fall through */
|
|
case 4 : a+=k[0]; break;
|
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
|
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
|
case 1 : a+=k8[0]; break;
|
|
case 0 : return c;
|
|
}
|
|
|
|
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
|
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
|
const uint8_t *k8;
|
|
|
|
/*--------------- all but last block: aligned reads and different mixing */
|
|
while (length > 12)
|
|
{
|
|
a += k[0] + (((uint32_t)k[1])<<16);
|
|
b += k[2] + (((uint32_t)k[3])<<16);
|
|
c += k[4] + (((uint32_t)k[5])<<16);
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 6;
|
|
}
|
|
|
|
/*----------------------------- handle the last (probably partial) block */
|
|
k8 = (const uint8_t *)k;
|
|
switch(length)
|
|
{
|
|
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
|
case 10: c+=k[4];
|
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 9 : c+=k8[8]; /* fall through */
|
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
|
case 6 : b+=k[2];
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 5 : b+=k8[4]; /* fall through */
|
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
|
case 2 : a+=k[0];
|
|
break;
|
|
case 1 : a+=k8[0];
|
|
break;
|
|
case 0 : return c; /* zero length requires no mixing */
|
|
}
|
|
|
|
} else { /* need to read the key one byte at a time */
|
|
const uint8_t *k = (const uint8_t *)key;
|
|
|
|
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += k[0];
|
|
a += ((uint32_t)k[1])<<8;
|
|
a += ((uint32_t)k[2])<<16;
|
|
a += ((uint32_t)k[3])<<24;
|
|
b += k[4];
|
|
b += ((uint32_t)k[5])<<8;
|
|
b += ((uint32_t)k[6])<<16;
|
|
b += ((uint32_t)k[7])<<24;
|
|
c += k[8];
|
|
c += ((uint32_t)k[9])<<8;
|
|
c += ((uint32_t)k[10])<<16;
|
|
c += ((uint32_t)k[11])<<24;
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 12;
|
|
}
|
|
|
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 12: c+=((uint32_t)k[11])<<24;
|
|
case 11: c+=((uint32_t)k[10])<<16;
|
|
case 10: c+=((uint32_t)k[9])<<8;
|
|
case 9 : c+=k[8];
|
|
|
|
case 8 : b+=((uint32_t)k[7])<<24;
|
|
case 7 : b+=((uint32_t)k[6])<<16;
|
|
case 6 : b+=((uint32_t)k[5])<<8;
|
|
case 5 : b+=k[4];
|
|
|
|
case 4 : a+=((uint32_t)k[3])<<24;
|
|
case 3 : a+=((uint32_t)k[2])<<16;
|
|
case 2 : a+=((uint32_t)k[1])<<8;
|
|
case 1 : a+=k[0];
|
|
break;
|
|
|
|
case 0 : return c;
|
|
}
|
|
}
|
|
|
|
final(a,b,c);
|
|
return c;
|
|
}
|
|
|
|
|
|
/*
|
|
* hashlittle2: return 2 32-bit hash values
|
|
*
|
|
* This is identical to hashlittle(), except it returns two 32-bit hash
|
|
* values instead of just one. This is good enough for hash table
|
|
* lookup with 2^^64 buckets, or if you want a second hash if you're not
|
|
* happy with the first, or if you want a probably-unique 64-bit ID for
|
|
* the key. *pc is better mixed than *pb, so use *pc first. If you want
|
|
* a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
|
|
*/
|
|
void hashlittle2(
|
|
const void *key, /* the key to hash */
|
|
size_t length, /* length of the key */
|
|
uint32_t *pc, /* IN: primary initval, OUT: primary hash */
|
|
uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */
|
|
{
|
|
uint32_t a,b,c; /* internal state */
|
|
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
|
|
|
|
/* Set up the internal state */
|
|
a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc;
|
|
c += *pb;
|
|
|
|
u.ptr = key;
|
|
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
|
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
|
const uint8_t *k8;
|
|
|
|
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += k[0];
|
|
b += k[1];
|
|
c += k[2];
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 3;
|
|
}
|
|
|
|
/*----------------------------- handle the last (probably partial) block */
|
|
|
|
k8 = (const uint8_t *)k;
|
|
switch(length)
|
|
{
|
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
|
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
|
case 9 : c+=k8[8]; /* fall through */
|
|
case 8 : b+=k[1]; a+=k[0]; break;
|
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
|
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
|
case 5 : b+=k8[4]; /* fall through */
|
|
case 4 : a+=k[0]; break;
|
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
|
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
|
case 1 : a+=k8[0]; break;
|
|
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
|
}
|
|
|
|
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
|
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
|
const uint8_t *k8;
|
|
|
|
/*--------------- all but last block: aligned reads and different mixing */
|
|
while (length > 12)
|
|
{
|
|
a += k[0] + (((uint32_t)k[1])<<16);
|
|
b += k[2] + (((uint32_t)k[3])<<16);
|
|
c += k[4] + (((uint32_t)k[5])<<16);
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 6;
|
|
}
|
|
|
|
/*----------------------------- handle the last (probably partial) block */
|
|
k8 = (const uint8_t *)k;
|
|
switch(length)
|
|
{
|
|
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
|
case 10: c+=k[4];
|
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 9 : c+=k8[8]; /* fall through */
|
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
|
case 6 : b+=k[2];
|
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 5 : b+=k8[4]; /* fall through */
|
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
|
break;
|
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
|
case 2 : a+=k[0];
|
|
break;
|
|
case 1 : a+=k8[0];
|
|
break;
|
|
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
|
}
|
|
|
|
} else { /* need to read the key one byte at a time */
|
|
const uint8_t *k = (const uint8_t *)key;
|
|
|
|
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += k[0];
|
|
a += ((uint32_t)k[1])<<8;
|
|
a += ((uint32_t)k[2])<<16;
|
|
a += ((uint32_t)k[3])<<24;
|
|
b += k[4];
|
|
b += ((uint32_t)k[5])<<8;
|
|
b += ((uint32_t)k[6])<<16;
|
|
b += ((uint32_t)k[7])<<24;
|
|
c += k[8];
|
|
c += ((uint32_t)k[9])<<8;
|
|
c += ((uint32_t)k[10])<<16;
|
|
c += ((uint32_t)k[11])<<24;
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 12;
|
|
}
|
|
|
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 12: c+=((uint32_t)k[11])<<24;
|
|
case 11: c+=((uint32_t)k[10])<<16;
|
|
case 10: c+=((uint32_t)k[9])<<8;
|
|
case 9 : c+=k[8];
|
|
case 8 : b+=((uint32_t)k[7])<<24;
|
|
case 7 : b+=((uint32_t)k[6])<<16;
|
|
case 6 : b+=((uint32_t)k[5])<<8;
|
|
case 5 : b+=k[4];
|
|
case 4 : a+=((uint32_t)k[3])<<24;
|
|
case 3 : a+=((uint32_t)k[2])<<16;
|
|
case 2 : a+=((uint32_t)k[1])<<8;
|
|
case 1 : a+=k[0];
|
|
break;
|
|
case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */
|
|
}
|
|
}
|
|
|
|
final(a,b,c);
|
|
*pc=c; *pb=b;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* hashbig():
|
|
* This is the same as hashword() on big-endian machines. It is different
|
|
* from hashlittle() on all machines. hashbig() takes advantage of
|
|
* big-endian byte ordering.
|
|
*/
|
|
uint32_t hashbig( const void *key, size_t length, uint32_t initval)
|
|
{
|
|
uint32_t a,b,c;
|
|
union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
|
|
|
|
/* Set up the internal state */
|
|
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
|
|
|
u.ptr = key;
|
|
if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
|
|
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
|
const uint8_t *k8;
|
|
|
|
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += k[0];
|
|
b += k[1];
|
|
c += k[2];
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 3;
|
|
}
|
|
|
|
/*----------------------------- handle the last (probably partial) block */
|
|
|
|
k8 = (const uint8_t *)k;
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
|
case 11: c+=((uint32_t)k8[10])<<8; /* fall through */
|
|
case 10: c+=((uint32_t)k8[9])<<16; /* fall through */
|
|
case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */
|
|
case 8 : b+=k[1]; a+=k[0]; break;
|
|
case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */
|
|
case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */
|
|
case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */
|
|
case 4 : a+=k[0]; break;
|
|
case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */
|
|
case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */
|
|
case 1 : a+=((uint32_t)k8[0])<<24; break;
|
|
case 0 : return c;
|
|
}
|
|
|
|
} else { /* need to read the key one byte at a time */
|
|
const uint8_t *k = (const uint8_t *)key;
|
|
|
|
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
|
while (length > 12)
|
|
{
|
|
a += ((uint32_t)k[0])<<24;
|
|
a += ((uint32_t)k[1])<<16;
|
|
a += ((uint32_t)k[2])<<8;
|
|
a += ((uint32_t)k[3]);
|
|
b += ((uint32_t)k[4])<<24;
|
|
b += ((uint32_t)k[5])<<16;
|
|
b += ((uint32_t)k[6])<<8;
|
|
b += ((uint32_t)k[7]);
|
|
c += ((uint32_t)k[8])<<24;
|
|
c += ((uint32_t)k[9])<<16;
|
|
c += ((uint32_t)k[10])<<8;
|
|
c += ((uint32_t)k[11]);
|
|
mix(a,b,c);
|
|
length -= 12;
|
|
k += 12;
|
|
}
|
|
|
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
|
switch(length) /* all the case statements fall through */
|
|
{
|
|
case 12: c+=k[11];
|
|
case 11: c+=((uint32_t)k[10])<<8;
|
|
case 10: c+=((uint32_t)k[9])<<16;
|
|
case 9 : c+=((uint32_t)k[8])<<24;
|
|
case 8 : b+=k[7];
|
|
case 7 : b+=((uint32_t)k[6])<<8;
|
|
case 6 : b+=((uint32_t)k[5])<<16;
|
|
case 5 : b+=((uint32_t)k[4])<<24;
|
|
case 4 : a+=k[3];
|
|
case 3 : a+=((uint32_t)k[2])<<8;
|
|
case 2 : a+=((uint32_t)k[1])<<16;
|
|
case 1 : a+=((uint32_t)k[0])<<24;
|
|
break;
|
|
case 0 : return c;
|
|
}
|
|
}
|
|
|
|
final(a,b,c);
|
|
return c;
|
|
}
|
|
|
|
|
|
uint32_t hashLookup3Orig (const char * k, int length) {
|
|
return hashlittle (k, length, 0);
|
|
}
|
|
|
|
uint32_t hashLookup3 (const char * k, int length) {
|
|
return Foam::Hasher(k, length, 0);
|
|
}
|
|
|
|
|
|
|
|
/* ======================================================================== */
|
|
|
|
static uint32_t crc_16_table[16] = {
|
|
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
|
|
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
|
|
};
|
|
|
|
/*
|
|
* This code was found at: http://wannabe.guru.org/alg/node191.html
|
|
* and still exists here: http://www.fearme.com/misc/alg/node191.html
|
|
*
|
|
* this source code is based on Rex and Binstock which, in turn,
|
|
* acknowledges William James Hunt.
|
|
*
|
|
* According to the site this CRC uses the polynomial x^16+x^5+x^2+1.
|
|
* Unfortunately, DOCSIS uses x^16+x^12+x^5+1. D'oh!
|
|
*/
|
|
|
|
static uint32_t GetCRC16Update
|
|
(
|
|
uint32_t start_crc,
|
|
const char * data_stream,
|
|
int length
|
|
) {
|
|
uint32_t crc = start_crc;
|
|
uint32_t r;
|
|
|
|
/* while there is more data to process */
|
|
while (length-- > 0) {
|
|
|
|
/* compute checksum of lower four bits of *data_stream */
|
|
r = crc_16_table[crc & 0xF];
|
|
crc = (crc >> 4) & 0x0FFF;
|
|
crc ^= r ^ crc_16_table[*data_stream & 0xF];
|
|
|
|
/* now compute checksum of upper four bits of *data_stream */
|
|
r = crc_16_table[crc & 0xF];
|
|
crc = (crc >> 4) & 0x0FFF;
|
|
crc ^= r ^ crc_16_table[(*data_stream >> 4) & 0xF];
|
|
|
|
/* next... */
|
|
data_stream++;
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
uint32_t GetCRC16 (const char * data_stream, int length) {
|
|
return GetCRC16Update (0, data_stream, length);
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
static uint32_t crc_table[256];
|
|
|
|
/* This code was found at:
|
|
* http://cell.onecall.net/cell-relay/publications/software/CRC/32bitCRC.c.html
|
|
*/
|
|
|
|
/* */
|
|
/* crc32h.c -- package to compute 32-bit CRC one byte at a time using */
|
|
/* the high-bit first (Big-Endian) bit ordering convention */
|
|
/* */
|
|
/* Synopsis: */
|
|
/* gen_crc_table() -- generates a 256-word table containing all CRC */
|
|
/* remainders for every possible 8-bit byte. It */
|
|
/* must be executed (once) before any CRC updates. */
|
|
/* */
|
|
/* unsigned update_crc(crc_accum, data_blk_ptr, data_blk_size) */
|
|
/* unsigned crc_accum; char *data_blk_ptr; int data_blk_size; */
|
|
/* Returns the updated value of the CRC accumulator after */
|
|
/* processing each byte in the addressed block of data. */
|
|
/* */
|
|
/* It is assumed that an unsigned long is at least 32 bits wide and */
|
|
/* that the predefined type char occupies one 8-bit byte of storage. */
|
|
/* */
|
|
/* The generator polynomial used for this version of the package is */
|
|
/* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 */
|
|
/* as specified in the Autodin/Ethernet/ADCCP protocol standards. */
|
|
/* Other degree 32 polynomials may be substituted by re-defining the */
|
|
/* symbol POLYNOMIAL below. Lower degree polynomials must first be */
|
|
/* multiplied by an appropriate power of x. The representation used */
|
|
/* is that the coefficient of x^0 is stored in the LSB of the 32-bit */
|
|
/* word and the coefficient of x^31 is stored in the most significant */
|
|
/* bit. The CRC is to be appended to the data most significant byte */
|
|
/* first. For those protocols in which bytes are transmitted MSB */
|
|
/* first and in the same order as they are encountered in the block */
|
|
/* this convention results in the CRC remainder being transmitted with */
|
|
/* the coefficient of x^31 first and with that of x^0 last (just as */
|
|
/* would be done by a hardware shift register mechanization). */
|
|
/* */
|
|
/* The table lookup technique was adapted from the algorithm described */
|
|
/* by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).*/
|
|
|
|
/* generate the table of CRC remainders for all possible bytes */
|
|
|
|
#define CRC32POLYNOMIAL 0x04c11db7L
|
|
|
|
static void GenerateCRC32Table (void) {
|
|
register int i, j;
|
|
register uint32_t crc_accum;
|
|
|
|
for ( i = 0; i < 256; i++ ) {
|
|
crc_accum = ( (unsigned long) i << 24 );
|
|
for ( j = 0; j < 8; j++ ) {
|
|
if ( crc_accum & 0x80000000L ) {
|
|
crc_accum = ( crc_accum << 1 ) ^ CRC32POLYNOMIAL;
|
|
} else {
|
|
crc_accum = ( crc_accum << 1 );
|
|
}
|
|
}
|
|
crc_table[i] = crc_accum;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* update the CRC on the data block one byte at a time */
|
|
|
|
static uint32_t UpdateCRC32
|
|
(
|
|
uint32_t crc_accum,
|
|
const char *data_blk_ptr,
|
|
int data_blk_size
|
|
) {
|
|
register int j;
|
|
register uint8_t i;
|
|
|
|
for (j = 0; j < data_blk_size; j++) {
|
|
i = (crc_accum >> 24) ^ *data_blk_ptr++;
|
|
crc_accum = (crc_accum << 8) ^ crc_table[i];
|
|
}
|
|
return crc_accum;
|
|
}
|
|
|
|
uint32_t GetCRC32 (const char * data_stream, int length) {
|
|
return UpdateCRC32 (0, data_stream, length);
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
/* Performs two parallel CRC-32 on even and odd bytes of the input, then
|
|
combines the two in a further CRC-32 calculation */
|
|
|
|
uint32_t GetCRC32PH (const char *data_blk_ptr, int data_blk_size) {
|
|
int j;
|
|
uint8_t i0, i1;
|
|
uint32_t crc_accum0 = 0, crc_accum1 = 0x23456789u;
|
|
|
|
if (data_blk_size & 1) crc_accum0 ^= *data_blk_ptr++;
|
|
for (j = 1; j < data_blk_size; j+=2) {
|
|
i0 = ((crc_accum0 >> 24) ^ *data_blk_ptr++);
|
|
i1 = ((crc_accum1 >> 24) ^ *data_blk_ptr++);
|
|
crc_accum0 = (crc_accum0 << 8) ^ crc_table[i0];
|
|
crc_accum1 = (crc_accum1 << 8) ^ crc_table[i1];
|
|
}
|
|
return crc_accum0 + crc_accum1;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
/* Fowler / Noll / Vo (FNV) Hash
|
|
|
|
http://www.isthe.com/chongo/tech/comp/fnv/ */
|
|
|
|
uint32_t FNVHash (const char * data, int len) {
|
|
int i;
|
|
uint32_t hash;
|
|
|
|
hash = 2166136261u;
|
|
for (i=0; i < len; i++) {
|
|
hash = (16777619u * hash) ^ data[i];
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
/*
|
|
* http://burtleburtle.net/bob/hash/doobs.html
|
|
*/
|
|
|
|
uint32_t oneAtATimeHash (const char * s, int len) {
|
|
int32_t hash;
|
|
int i;
|
|
|
|
for (hash = 0, i = 0; i < len; i++) {
|
|
hash += s[i];
|
|
hash += (hash << 10);
|
|
hash ^= (hash >> 6); /* Non-portable due to ANSI C */
|
|
}
|
|
hash += (hash << 3);
|
|
hash ^= (hash >> 11); /* Non-portable due to ANSI C */
|
|
hash += (hash << 15);
|
|
return (uint32_t) hash;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
uint32_t oneAtATimeHashPH (const char * s, int len) {
|
|
int32_t hash0 = 0, hash1 = 0x23456789;
|
|
int i;
|
|
|
|
if (len & 1) hash1 ^= *s++;
|
|
|
|
for (i = 1; i < len; i+=2) {
|
|
hash0 += *s++;
|
|
hash1 += *s++;
|
|
hash0 += (hash0 << 10);
|
|
hash1 += (hash1 << 10);
|
|
hash0 ^= (hash0 >> 6); /* Non-portable due to ANSI C */
|
|
hash1 ^= (hash1 >> 6); /* Non-portable due to ANSI C */
|
|
}
|
|
|
|
hash0 += hash1;
|
|
|
|
hash0 += (hash0 << 3);
|
|
hash0 ^= (hash0 >> 11); /* Non-portable due to ANSI C */
|
|
hash0 += (hash0 << 15);
|
|
return (uint32_t) hash0;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
|
|
license. See:
|
|
http://www.azillionmonkeys.com/qed/weblicense.html for license details.
|
|
|
|
http://www.azillionmonkeys.com/qed/hash.html */
|
|
|
|
#undef get16bits
|
|
#if 0
|
|
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
|
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
|
#define get16bits(d) (*((const uint16_t *) (d)))
|
|
#endif
|
|
#endif
|
|
|
|
#if !defined (get16bits)
|
|
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
|
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
|
#endif
|
|
|
|
uint32_t SuperFastHash (const char * data, int len)
|
|
{
|
|
uint32_t hash = 0;
|
|
|
|
if (len <= 0 || data == NULL) return 0;
|
|
|
|
unsigned rem = len & 3;
|
|
len >>= 2;
|
|
|
|
/* Main loop */
|
|
for (;len > 0; len--) {
|
|
hash += get16bits(data);
|
|
hash = (hash << 16) ^ ((get16bits(data+2) << 11) ^ hash);
|
|
hash += hash >> 11;
|
|
data += 2*sizeof(uint16_t);
|
|
}
|
|
|
|
/* Handle end cases */
|
|
switch (rem) {
|
|
case 3 :
|
|
hash += get16bits(data);
|
|
hash ^= hash << 16;
|
|
hash ^= data[sizeof (uint16_t)] << 18;
|
|
hash += hash >> 11;
|
|
break;
|
|
|
|
case 2 :
|
|
hash += get16bits (data);
|
|
hash ^= hash << 11;
|
|
hash += hash >> 17;
|
|
break;
|
|
|
|
case 1 : hash += *data;
|
|
hash ^= hash << 10;
|
|
hash += hash >> 1;
|
|
}
|
|
|
|
/* Force "avalanching" of final 127 bits */
|
|
hash ^= hash << 3;
|
|
hash += hash >> 5;
|
|
hash ^= hash << 4;
|
|
hash += hash >> 17;
|
|
hash ^= hash << 25;
|
|
hash += hash >> 6;
|
|
|
|
return hash;
|
|
}
|
|
|
|
/* ======================================================================== */
|
|
|
|
/* A hashing function that I believe was created by either Chris Torek or
|
|
Dan Bernstein */
|
|
|
|
uint32_t alphaNumHash (const char * s, int len) {
|
|
uint32_t h;
|
|
int i;
|
|
|
|
for (h = 0, i = 0; i < len; i++) {
|
|
h = (h << 5) + (h * 5) + (unsigned char) s[i];
|
|
}
|
|
return h;
|
|
}
|
|
|
|
uint32_t bernstein (const char * s, int len) {
|
|
uint32_t h;
|
|
int i;
|
|
|
|
for (h = 0, i = 0; i < len; i++) {
|
|
h = (h << 5) + h + (unsigned char) s[i];
|
|
}
|
|
return h;
|
|
}
|
|
|
|
|
|
// found somewhere in the 2nd addition
|
|
uint32_t stroustrup (const char * s, int len) {
|
|
uint32_t h;
|
|
|
|
for (register int i=0; i < len; ++s, ++i)
|
|
{
|
|
h = (h << 1) ^ (unsigned char) s[i];
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
|
|
/* ======================================================================== */
|
|
|
|
typedef uint32_t (* hashFn) (const char * s, int len);
|
|
|
|
#define BUFF_SZ (128*2)
|
|
#define NTESTS 5000000
|
|
|
|
double test (hashFn hash) {
|
|
static char buff[BUFF_SZ];
|
|
clock_t c0, c1;
|
|
int32_t i;
|
|
|
|
for (buff[0]=0, i=1; i < BUFF_SZ; i++) buff[i] = (char) (i + buff[i-1]);
|
|
|
|
c0 = clock ();
|
|
for (i=0; i < NTESTS; i++) hash (buff, BUFF_SZ);
|
|
c1 = clock ();
|
|
return (c1 - c0)*(1.0 / (double)CLOCKS_PER_SEC);
|
|
}
|
|
|
|
struct tagtest {
|
|
double res;
|
|
char * name;
|
|
hashFn hash;
|
|
} tests[] = {
|
|
// { 0.0, "CRC32\t\t", GetCRC32 },
|
|
// { 0.0, "oneAtATimeHash\t", oneAtATimeHash },
|
|
// { 0.0, "alphaNumHash\t", alphaNumHash },
|
|
{ 0.0, "FNVHash\t\t", FNVHash },
|
|
{ 0.0, "bernstein\t", bernstein },
|
|
{ 0.0, "stroustrup\t", stroustrup },
|
|
{ 0.0, "hashLookup3\t", hashLookup3 },
|
|
{ 0.0, "hashLookup3Orig\t", hashLookup3Orig },
|
|
{ 0.0, "SuperFastHash\t", SuperFastHash },
|
|
{ 0.0, NULL, NULL }
|
|
};
|
|
|
|
int main () {
|
|
int i, j;
|
|
GenerateCRC32Table ();
|
|
|
|
for (j=0; tests[j].name != NULL; j++) {
|
|
for (i=0; i < 3; i++) {
|
|
double res = test (tests[j].hash);
|
|
if (tests[j].res == 0.0 || tests[j].res > res) tests[j].res = res;
|
|
}
|
|
printf ("%s:%8.4fs\n", tests[j].name, tests[j].res);
|
|
}
|
|
|
|
return 0;
|
|
}
|