1266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
2266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
3266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandlookup3.c, by Bob Jenkins, May 2006, Public Domain.
4266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
5266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThese are functions for producing 32-bit hashes for hash table lookup.
6266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandhashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
7266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandare externally useful functions.  Routines to test the hash are included
8266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandif SELF_TEST is defined.  You can use this free for any purpose.  It's in
9266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthe public domain.  It has no warranty.
10266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
11266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandYou probably want to use hashlittle().  hashlittle() and hashbig()
12266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandhash byte arrays.  hashlittle() is is faster than hashbig() on
13266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandlittle-endian machines.  Intel and AMD are little-endian machines.
14266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandOn second thought, you probably want hashlittle2(), which is identical to
15266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandhashlittle() except it returns two 32-bit hashes for the price of one.
16266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandYou could implement hashbig2() if you wanted but I haven't bothered here.
17266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
18266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandIf you want to find a hash of, say, exactly 7 integers, do
19266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = i1;  b = i2;  c = i3;
20266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  mix(a,b,c);
21266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a += i4; b += i5; c += i6;
22266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  mix(a,b,c);
23266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a += i7;
24266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  final(a,b,c);
25266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthen use c as the hash value.  If you have a variable length array of
26266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand4-byte integers to hash, use hashword().  If you have a byte array (like
27266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanda character string), use hashlittle().  If you have several byte arrays, or
28266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanda mix of things, see the comments above hashlittle().
29266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
30266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandWhy is this so big?  I read 12 bytes at a time into 3 4-byte integers,
31266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthen mix those integers.  This is fast (you can do a lot more thorough
32266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandmixing with 12*3 instructions on 3 integers than you can with 3 instructions
33266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandon 1 byte), but shoehorning those bytes into integers efficiently is messy.
34266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
35266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
36266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define SELF_TEST 1
37266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#undef SELF_TEST
38266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
39266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#include <stdio.h>      /* defines printf for tests */
40266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#include <time.h>       /* defines time_t for timings in the test */
41266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#include <stdint.h>     /* defines uint32_t etc */
42266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#include <sys/param.h>  /* attempt to define endianness */
43266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#ifdef linux
44266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# include <endian.h>    /* attempt to define endianness */
45266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif
46266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
47266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
48266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * My best guess at if you are big-endian or little-endian.  This may
49266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * need adjustment.
50266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand */
51266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
52266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     __BYTE_ORDER == __LITTLE_ENDIAN) || \
53266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    (defined(i386) || defined(__i386__) || defined(__i486__) || \
54266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
55266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_LITTLE_ENDIAN 1
56266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_BIG_ENDIAN 0
57266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
58266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand       __BYTE_ORDER == __BIG_ENDIAN) || \
59266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
60266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_LITTLE_ENDIAN 0
61266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_BIG_ENDIAN 1
62266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#else
63266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_LITTLE_ENDIAN 0
64266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand# define HASH_BIG_ENDIAN 0
65266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif
66266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
67266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define hashsize(n) ((uint32_t)1<<(n))
68266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define hashmask(n) (hashsize(n)-1)
69266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
70266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
71266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
72266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
73266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandmix -- mix 3 32-bit values reversibly.
74266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
75266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThis is reversible, so any information in (a,b,c) before mix() is
76266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandstill in (a,b,c) after mix().
77266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
78266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandIf four pairs of (a,b,c) inputs are run through mix(), or through
79266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandmix() in reverse, there are at least 32 bits of the output that
80266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandare sometimes the same for one pair and different for another pair.
81266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThis was tested for:
82266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* pairs that differed by one bit, by two bits, in any combination
83266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  of top bits of (a,b,c), or in any combination of bottom bits of
84266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  (a,b,c).
85266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
86266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
87266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  is commonly produced by subtraction) look like a single 1-bit
88266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  difference.
89266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* the base values were pseudorandom, all zero but one bit set, or
90266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  all zero plus a counter that starts at zero.
91266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
92266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandSome k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
93266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandsatisfy this are
94266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    4  6  8 16 19  4
95266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    9 15  3 18 27 15
96266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand   14  9  3  7 17  3
97266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandWell, "9 15 3 18 27 15" didn't quite get 32 bits diffing
98266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandfor "differ" defined as + with a one-bit base and a two-bit delta.  I
99266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandused http://burtleburtle.net/bob/hash/avalanche.html to choose
100266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthe operations, constants, and arrangements of the variables.
101266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
102266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThis does not achieve avalanche.  There are input bits of (a,b,c)
103266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthat fail to affect some output bits of (a,b,c), especially of a.  The
104266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandmost thoroughly mixed value is c, but it doesn't really even achieve
105266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandavalanche in c.
106266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
107266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThis allows some parallelism.  Read-after-writes are good at doubling
108266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthe number of bits affected, so the goal of mixing pulls in the opposite
109266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanddirection as the goal of parallelism.  I did what I could.  Rotates
110266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandseem to cost as much as shifts on every machine I could lay my hands
111266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandon, and rotates are much kinder to the top and bottom bits, so I used
112266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandrotates.
113266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
114266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
115266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define mix(a,b,c) \
116266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{ \
1172128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (a) -= (c);  (a) ^= rot(c, 4);  (c) += (b); \
1182128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (b) -= (a);  (b) ^= rot(a, 6);  (a) += (c); \
1192128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (c) -= (b);  (c) ^= rot(b, 8);  (b) += (a); \
1202128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (a) -= (c);  (a) ^= rot(c,16);  (c) += (b); \
1212128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (b) -= (a);  (b) ^= rot(a,19);  (a) += (c); \
1222128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (c) -= (b);  (c) ^= rot(b, 4);  (b) += (a); \
123266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
124266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
125266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
126266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
127266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandfinal -- final mixing of 3 32-bit values (a,b,c) into c
128266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
129266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandPairs of (a,b,c) values differing in only a few bits will usually
130266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandproduce values of c that look totally different.  This was tested for
131266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* pairs that differed by one bit, by two bits, in any combination
132266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  of top bits of (a,b,c), or in any combination of bottom bits of
133266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  (a,b,c).
134266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
135266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
136266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  is commonly produced by subtraction) look like a single 1-bit
137266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  difference.
138266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand* the base values were pseudorandom, all zero but one bit set, or
139266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  all zero plus a counter that starts at zero.
140266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
141266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThese constants passed:
142266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand 14 11 25 16 4 14 24
143266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand 12 14 25 16 4 14 24
144266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandand these came close:
145266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  4  8 15 26 3 22 24
146266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand 10  8 15 26 3 22 24
147266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand 11  8 15 26 3 22 24
148266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
149266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
150266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define final(a,b,c) \
151266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{ \
1522128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (c) ^= (b); (c) -= rot(b,14); \
1532128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (a) ^= (c); (a) -= rot(c,11); \
1542128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (b) ^= (a); (b) -= rot(a,25); \
1552128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (c) ^= (b); (c) -= rot(b,16); \
1562128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (a) ^= (c); (a) -= rot(c,4);  \
1572128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (b) ^= (a); (b) -= rot(a,14); \
1582128f742bf722b49df303b659f4fc514135e8e12Chih-Hung Hsieh  (c) ^= (b); (c) -= rot(b,24); \
159266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
160266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
161266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
162266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand--------------------------------------------------------------------
163266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand This works on all machines.  To be useful, it requires
164266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand -- that the key be an array of uint32_t's, and
165266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand -- that the length be the number of uint32_t's in the key
166266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
167266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand The function hashword() is identical to hashlittle() on little-endian
168266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand machines, and identical to hashbig() on big-endian machines,
169266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand except that the length has to be measured in uint32_ts rather than in
170266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand bytes.  hashlittle() is more complicated than hashword() only because
171266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand hashlittle() has to dance around fitting the key bytes into registers.
172266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand--------------------------------------------------------------------
173266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
174266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t hashword(
175266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandconst uint32_t *k,                   /* the key, an array of uint32_t values */
176266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandsize_t          length,               /* the length of the key, in uint32_ts */
177266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t        initval)         /* the previous hash, or an arbitrary value */
178266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
179266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t a,b,c;
180266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
181266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* Set up the internal state */
182266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval;
183266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
184266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------------- handle most of the key */
185266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  while (length > 3)
186266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
187266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    a += k[0];
188266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    b += k[1];
189266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    c += k[2];
190266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    mix(a,b,c);
191266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    length -= 3;
192266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k += 3;
193266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
194266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
195266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------- handle the last 3 uint32_t's */
196266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  switch(length)                     /* all the case statements fall through */
197266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
198266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 3 : c+=k[2];
199266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 2 : b+=k[1];
200266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 1 : a+=k[0];
201266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    final(a,b,c);
202266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 0:     /* case 0: nothing left to add */
203266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    break;
204266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
205266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------------------ report the result */
206266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  return c;
207266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
208266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
209266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
210266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
211266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand--------------------------------------------------------------------
212266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandhashword2() -- same as hashword(), but take two seeds and return two
213266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand32-bit values.  pc and pb must both be nonnull, and *pc and *pb must
214266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandboth be initialized with seeds.  If you pass in (*pb)==0, the output
215266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand(*pc) will be the same as the return value from hashword().
216266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand--------------------------------------------------------------------
217266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
218266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid hashword2 (
219266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandconst uint32_t *k,                   /* the key, an array of uint32_t values */
220266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandsize_t          length,               /* the length of the key, in uint32_ts */
221266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t       *pc,                      /* IN: seed OUT: primary hash value */
222266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t       *pb)               /* IN: more seed OUT: secondary hash value */
223266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
224266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t a,b,c;
225266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
226266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* Set up the internal state */
227266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc;
228266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  c += *pb;
229266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
230266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------------- handle most of the key */
231266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  while (length > 3)
232266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
233266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    a += k[0];
234266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    b += k[1];
235266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    c += k[2];
236266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    mix(a,b,c);
237266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    length -= 3;
238266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k += 3;
239266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
240266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
241266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------- handle the last 3 uint32_t's */
242266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  switch(length)                     /* all the case statements fall through */
243266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
244266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 3 : c+=k[2];
245266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 2 : b+=k[1];
246266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 1 : a+=k[0];
247266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    final(a,b,c);
248266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  case 0:     /* case 0: nothing left to add */
249266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    break;
250266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
251266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /*------------------------------------------------------ report the result */
252266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  *pc=c; *pb=b;
253266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
254266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
255266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
256266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
257266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
258266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandhashlittle() -- hash a variable-length key into a 32-bit value
259266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  k       : the key (the unaligned variable-length array of bytes)
260266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  length  : the length of the key, counting by bytes
261266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  initval : can be any 4-byte value
262266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandReturns a 32-bit value.  Every bit of the key affects every bit of
263266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandthe return value.  Two keys differing by one or two bits will have
264266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandtotally different hash values.
265266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
266266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandThe best hash table sizes are powers of 2.  There is no need to do
267266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandmod a prime (mod is sooo slow!).  If you need less than 32 bits,
268266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduse a bitmask.  For example, if you need only 10 bits, do
269266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  h = (h & hashmask(10));
270266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandIn which case, the hash table should have hashsize(10) elements.
271266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
272266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandIf you are hashing n strings (uint8_t **)k, do it like this:
273266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
274266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
275266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandBy Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this
276266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandcode any way you wish, private, educational, or commercial.  It's free.
277266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
278266dde27811b78f466702295ba0173b8d8be5adaRom LemarchandUse for hash table lookup, or anything where one collision in 2^^32 is
279266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandacceptable.  Do NOT use for cryptographic purposes.
280266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand-------------------------------------------------------------------------------
281266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand*/
282266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
283266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t hashlittle( const void *key, size_t length, uint32_t initval)
284266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
285266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t a,b,c;                                          /* internal state */
286266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
287266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
288266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* Set up the internal state */
289266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
290266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
291266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  u.ptr = key;
292266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
293266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
294266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t  *k8;
295266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
296266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
297266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
298266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
299266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0];
300266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[1];
301266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[2];
302266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
303266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
304266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 3;
305266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
306266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
307266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*----------------------------- handle the last (probably partial) block */
308266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*
309266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * "k[2]&0xffffff" actually reads beyond the end of the string, but
310266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * then masks off the part it's not allowed to read.  Because the
311266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * string is aligned, the masked-off tail is in the same word as the
312266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * rest of the string.  Every machine with memory protection I've seen
313266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * does it on word boundaries, so is OK with this.  But VALGRIND will
314266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * still catch it and complain.  The masking trick does make the hash
315266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * noticably faster for short strings (like English words).
316266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     */
317266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#ifndef VALGRIND
318266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
319373d3c7257fa815d0b9ee8f16874470a6002042eChih-Hung Hsieh    (void) k8; // unused
320266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
321266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
322266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
323266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
324266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
325266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
326266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
327266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
328266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
329266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k[1]&0xff; a+=k[0]; break;
330266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
331266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=k[0]&0xffffff; break;
332266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=k[0]&0xffff; break;
333266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k[0]&0xff; break;
334266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;              /* zero length strings require no mixing */
335266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
336266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
337266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#else /* make valgrind happy */
338266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
339266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k8 = (const uint8_t *)k;
340266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
341266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
342266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
343266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
344266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
345266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k8[8];                   /* fall through */
346266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
347266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
348266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
349266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k8[4];                   /* fall through */
350266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
351266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
352266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
353266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k8[0]; break;
354266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;
355266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
356266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
357266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif /* !valgrind */
358266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
359266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
360266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
361266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t  *k8;
362266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
363266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*--------------- all but last block: aligned reads and different mixing */
364266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
365266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
366266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0] + (((uint32_t)k[1])<<16);
367266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[2] + (((uint32_t)k[3])<<16);
368266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[4] + (((uint32_t)k[5])<<16);
369266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
370266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
371266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 6;
372266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
373266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
374266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*----------------------------- handle the last (probably partial) block */
375266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k8 = (const uint8_t *)k;
376266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
377266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
378266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
379266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             b+=k[2]+(((uint32_t)k[3])<<16);
380266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
381266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
382266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
383266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=k[4];
384266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             b+=k[2]+(((uint32_t)k[3])<<16);
385266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
386266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
387266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k8[8];                      /* fall through */
388266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
389266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
390266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
391266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
392266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=k[2];
393266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
394266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
395266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k8[4];                      /* fall through */
396266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
397266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
398266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
399266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=k[0];
400266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
401266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k8[0];
402266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
403266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;                     /* zero length requires no mixing */
404266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
405266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
406266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  } else {                        /* need to read the key one byte at a time */
407266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t *k = (const uint8_t *)key;
408266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
409266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
410266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
411266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
412266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0];
413266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[1])<<8;
414266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[2])<<16;
415266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[3])<<24;
416266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[4];
417266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[5])<<8;
418266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[6])<<16;
419266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[7])<<24;
420266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[8];
421266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[9])<<8;
422266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[10])<<16;
423266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[11])<<24;
424266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
425266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
426266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 12;
427266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
428266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
429266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*-------------------------------- last block: affect all 32 bits of (c) */
430266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)                   /* all the case statements fall through */
431266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
432266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=((uint32_t)k[11])<<24;
433266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k[10])<<16;
434266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k[9])<<8;
435266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k[8];
436266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=((uint32_t)k[7])<<24;
437266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k[6])<<16;
438266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k[5])<<8;
439266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k[4];
440266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=((uint32_t)k[3])<<24;
441266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k[2])<<16;
442266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k[1])<<8;
443266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k[0];
444266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
445266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;
446266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
447266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
448266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
449266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  final(a,b,c);
450266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  return c;
451266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
452266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
453266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
454266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
455266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * hashlittle2: return 2 32-bit hash values
456266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand *
457266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * This is identical to hashlittle(), except it returns two 32-bit hash
458266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * values instead of just one.  This is good enough for hash table
459266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * lookup with 2^^64 buckets, or if you want a second hash if you're not
460266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * happy with the first, or if you want a probably-unique 64-bit ID for
461266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * the key.  *pc is better mixed than *pb, so use *pc first.  If you want
462266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
463266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand */
464266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid hashlittle2(
465266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  const void *key,       /* the key to hash */
466266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  size_t      length,    /* length of the key */
467266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t   *pc,        /* IN: primary initval, OUT: primary hash */
468266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t   *pb)        /* IN: secondary initval, OUT: secondary hash */
469266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
470266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t a,b,c;                                          /* internal state */
471266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
472266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
473266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* Set up the internal state */
474266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc;
475266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  c += *pb;
476266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
477266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  u.ptr = key;
478266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
479266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
480266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t  *k8;
481266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
482266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
483266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
484266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
485266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0];
486266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[1];
487266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[2];
488266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
489266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
490266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 3;
491266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
492266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
493266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*----------------------------- handle the last (probably partial) block */
494266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*
495266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * "k[2]&0xffffff" actually reads beyond the end of the string, but
496266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * then masks off the part it's not allowed to read.  Because the
497266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * string is aligned, the masked-off tail is in the same word as the
498266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * rest of the string.  Every machine with memory protection I've seen
499266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * does it on word boundaries, so is OK with this.  But VALGRIND will
500266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * still catch it and complain.  The masking trick does make the hash
501266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * noticably faster for short strings (like English words).
502266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     */
503266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#ifndef VALGRIND
504266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
505373d3c7257fa815d0b9ee8f16874470a6002042eChih-Hung Hsieh    (void) k8; // unused
506266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
507266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
508266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
509266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
510266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
511266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
512266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
513266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
514266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
515266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k[1]&0xff; a+=k[0]; break;
516266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
517266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=k[0]&0xffffff; break;
518266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=k[0]&0xffff; break;
519266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k[0]&0xff; break;
520266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
521266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
522266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
523266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#else /* make valgrind happy */
524266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
525266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k8 = (const uint8_t *)k;
526266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
527266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
528266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
529266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
530266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
531266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k8[8];                   /* fall through */
532266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
533266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
534266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
535266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k8[4];                   /* fall through */
536266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
537266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
538266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
539266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k8[0]; break;
540266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
541266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
542266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
543266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif /* !valgrind */
544266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
545266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
546266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
547266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t  *k8;
548266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
549266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*--------------- all but last block: aligned reads and different mixing */
550266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
551266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
552266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0] + (((uint32_t)k[1])<<16);
553266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[2] + (((uint32_t)k[3])<<16);
554266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[4] + (((uint32_t)k[5])<<16);
555266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
556266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
557266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 6;
558266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
559266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
560266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*----------------------------- handle the last (probably partial) block */
561266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k8 = (const uint8_t *)k;
562266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
563266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
564266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
565266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             b+=k[2]+(((uint32_t)k[3])<<16);
566266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
567266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
568266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
569266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=k[4];
570266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             b+=k[2]+(((uint32_t)k[3])<<16);
571266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
572266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
573266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k8[8];                      /* fall through */
574266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
575266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
576266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
577266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
578266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=k[2];
579266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             a+=k[0]+(((uint32_t)k[1])<<16);
580266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
581266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k8[4];                      /* fall through */
582266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
583266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
584266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
585266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=k[0];
586266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
587266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k8[0];
588266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
589266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
590266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
591266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
592266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  } else {                        /* need to read the key one byte at a time */
593266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t *k = (const uint8_t *)key;
594266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
595266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
596266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
597266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
598266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0];
599266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[1])<<8;
600266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[2])<<16;
601266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[3])<<24;
602266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[4];
603266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[5])<<8;
604266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[6])<<16;
605266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[7])<<24;
606266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[8];
607266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[9])<<8;
608266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[10])<<16;
609266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[11])<<24;
610266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
611266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
612266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 12;
613266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
614266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
615266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*-------------------------------- last block: affect all 32 bits of (c) */
616266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)                   /* all the case statements fall through */
617266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
618266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=((uint32_t)k[11])<<24;
619266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k[10])<<16;
620266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k[9])<<8;
621266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k[8];
622266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=((uint32_t)k[7])<<24;
623266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k[6])<<16;
624266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k[5])<<8;
625266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k[4];
626266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=((uint32_t)k[3])<<24;
627266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k[2])<<16;
628266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k[1])<<8;
629266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k[0];
630266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
631266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : *pc=c; *pb=b; return;  /* zero length strings require no mixing */
632266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
633266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
634266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
635266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  final(a,b,c);
636266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  *pc=c; *pb=b;
637266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
638266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
639266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
640266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
641266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/*
642266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * hashbig():
643266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * This is the same as hashword() on big-endian machines.  It is different
644266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * from hashlittle() on all machines.  hashbig() takes advantage of
645266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand * big-endian byte ordering.
646266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand */
647266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchanduint32_t hashbig( const void *key, size_t length, uint32_t initval)
648266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
649266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t a,b,c;
650266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */
651266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
652266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* Set up the internal state */
653266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
654266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
655266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  u.ptr = key;
656266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) {
657266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
658266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t  *k8;
659266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
660266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
661266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
662266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
663266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += k[0];
664266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += k[1];
665266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += k[2];
666266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
667266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
668266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 3;
669266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
670266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
671266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*----------------------------- handle the last (probably partial) block */
672266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*
673266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * "k[2]<<8" actually reads beyond the end of the string, but
674266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * then shifts out the part it's not allowed to read.  Because the
675266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * string is aligned, the illegal read is in the same word as the
676266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * rest of the string.  Every machine with memory protection I've seen
677266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * does it on word boundaries, so is OK with this.  But VALGRIND will
678266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * still catch it and complain.  The masking trick does make the hash
679266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     * noticably faster for short strings (like English words).
680266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand     */
681266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#ifndef VALGRIND
682266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
683373d3c7257fa815d0b9ee8f16874470a6002042eChih-Hung Hsieh    (void) k8; // unused
684266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)
685266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
686266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
687266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;
688266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;
689266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;
690266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
691266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;
692266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;
693266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=k[1]&0xff000000; a+=k[0]; break;
694266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
695266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=k[0]&0xffffff00; break;
696266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=k[0]&0xffff0000; break;
697266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=k[0]&0xff000000; break;
698266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;              /* zero length strings require no mixing */
699266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
700266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
701266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#else  /* make valgrind happy */
702266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
703266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    k8 = (const uint8_t *)k;
704266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)                   /* all the case statements fall through */
705266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
706266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
707266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k8[10])<<8;  /* fall through */
708266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k8[9])<<16;  /* fall through */
709266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=((uint32_t)k8[8])<<24;  /* fall through */
710266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[1]; a+=k[0]; break;
711266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k8[6])<<8;   /* fall through */
712266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k8[5])<<16;  /* fall through */
713266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=((uint32_t)k8[4])<<24;  /* fall through */
714266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[0]; break;
715266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k8[2])<<8;   /* fall through */
716266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k8[1])<<16;  /* fall through */
717266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=((uint32_t)k8[0])<<24; break;
718266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;
719266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
720266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
721266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif /* !VALGRIND */
722266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
723266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  } else {                        /* need to read the key one byte at a time */
724266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    const uint8_t *k = (const uint8_t *)key;
725266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
726266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
727266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    while (length > 12)
728266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
729266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[0])<<24;
730266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[1])<<16;
731266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[2])<<8;
732266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      a += ((uint32_t)k[3]);
733266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[4])<<24;
734266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[5])<<16;
735266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[6])<<8;
736266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      b += ((uint32_t)k[7]);
737266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[8])<<24;
738266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[9])<<16;
739266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[10])<<8;
740266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      c += ((uint32_t)k[11]);
741266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      mix(a,b,c);
742266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      length -= 12;
743266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      k += 12;
744266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
745266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
746266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    /*-------------------------------- last block: affect all 32 bits of (c) */
747266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    switch(length)                   /* all the case statements fall through */
748266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
749266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 12: c+=k[11];
750266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 11: c+=((uint32_t)k[10])<<8;
751266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 10: c+=((uint32_t)k[9])<<16;
752266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 9 : c+=((uint32_t)k[8])<<24;
753266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 8 : b+=k[7];
754266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 7 : b+=((uint32_t)k[6])<<8;
755266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 6 : b+=((uint32_t)k[5])<<16;
756266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 5 : b+=((uint32_t)k[4])<<24;
757266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 4 : a+=k[3];
758266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 3 : a+=((uint32_t)k[2])<<8;
759266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 2 : a+=((uint32_t)k[1])<<16;
760266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 1 : a+=((uint32_t)k[0])<<24;
761266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand             break;
762266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    case 0 : return c;
763266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
764266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
765266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
766266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  final(a,b,c);
767266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  return c;
768266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
769266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
770266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
771266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#ifdef SELF_TEST
772266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
773266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/* used for timings */
774266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid driver1()
775266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
776266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t buf[256];
777266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t i;
778266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t h=0;
779266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  time_t a,z;
780266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
781266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  time(&a);
782266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (i=0; i<256; ++i) buf[i] = 'x';
783266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (i=0; i<1; ++i)
784266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
785266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    h = hashlittle(&buf[0],1,h);
786266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
787266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  time(&z);
788266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (z-a > 0) printf("time %d %.8x\n", z-a, h);
789266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
790266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
791266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/* check that every input bit changes every output bit half the time */
792266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define HASHSTATE 1
793266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define HASHLEN   1
794266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define MAXPAIR 60
795266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#define MAXLEN  70
796266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid driver2()
797266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
798266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
799266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;
800266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
801266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t x[HASHSTATE],y[HASHSTATE];
802266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t hlen;
803266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
804266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
805266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (hlen=0; hlen < MAXLEN; ++hlen)
806266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
807266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    z=0;
808266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    for (i=0; i<hlen; ++i)  /*----------------------- for each input byte, */
809266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
810266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      for (j=0; j<8; ++j)   /*------------------------ for each input bit, */
811266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      {
812266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
813266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	{
814266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  for (l=0; l<HASHSTATE; ++l)
815266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);
816266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
817266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      	  /*---- check that every output bit is affected by that input bit */
818266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  for (k=0; k<MAXPAIR; k+=2)
819266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  {
820266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    uint32_t finished=1;
821266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    /* keys have one bit different */
822266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;}
823266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    /* have a and b be two keys differing in only one bit */
824266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    a[i] ^= (k<<j);
825266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    a[i] ^= (k>>(8-j));
826266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	     c[0] = hashlittle(a, hlen, m);
827266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    b[i] ^= ((k+1)<<j);
828266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    b[i] ^= ((k+1)>>(8-j));
829266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	     d[0] = hashlittle(b, hlen, m);
830266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    /* check every bit is 1, 0, set, and not set at least once */
831266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    for (l=0; l<HASHSTATE; ++l)
832266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    {
833266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      e[l] &= (c[l]^d[l]);
834266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      f[l] &= ~(c[l]^d[l]);
835266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      g[l] &= c[l];
836266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      h[l] &= ~c[l];
837266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      x[l] &= d[l];
838266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      y[l] &= ~d[l];
839266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	      if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
840266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    }
841266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	    if (finished) break;
842266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  }
843266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  if (k>z) z=k;
844266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  if (k==MAXPAIR)
845266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  {
846266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	     printf("Some bit didn't change: ");
847266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	     printf("%.8x %.8x %.8x %.8x %.8x %.8x  ",
848266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	            e[0],f[0],g[0],h[0],x[0],y[0]);
849266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	     printf("i %d j %d m %d len %d\n", i, j, m, hlen);
850266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  }
851266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	  if (z==MAXPAIR) goto done;
852266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	}
853266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      }
854266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
855266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand   done:
856266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    if (z < MAXPAIR)
857266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
858266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      printf("Mix success  %2d bytes  %2d initvals  ",i,m);
859266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      printf("required  %d  trials\n", z/2);
860266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
861266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
862266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("\n");
863266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
864266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
865266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/* Check for reading beyond the end of the buffer and alignment problems */
866266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid driver3()
867266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
868266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t buf[MAXLEN+20], *b;
869266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t len;
870266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t q[] = "This is the time for all good men to come to the aid of their country...";
871266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t h;
872266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";
873266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t i;
874266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
875266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t j;
876266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
877266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t ref,x,y;
878266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t *p;
879266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
880266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("Endianness.  These lines should all be the same (for values filled in):\n");
881266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("%.8x                            %.8x                            %.8x\n",
882266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13),
883266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13),
884266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13));
885266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  p = q;
886266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
887266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
888266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
889266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
890266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
891266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
892266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
893266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  p = &qq[1];
894266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
895266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
896266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
897266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
898266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
899266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
900266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
901266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  p = &qqq[2];
902266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
903266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
904266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
905266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
906266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
907266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
908266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
909266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  p = &qqqq[3];
910266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",
911266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
912266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
913266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
914266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
915266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
916266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
917266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("\n");
918266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
919266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* check that hashlittle2 and hashlittle produce the same results */
920266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  i=47; j=0;
921266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  hashlittle2(q, sizeof(q), &i, &j);
922266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (hashlittle(q, sizeof(q), 47) != i)
923266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    printf("hashlittle2 and hashlittle mismatch\n");
924266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
925266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* check that hashword2 and hashword produce the same results */
926266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  len = 0xdeadbeef;
927266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  i=47, j=0;
928266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  hashword2(&len, 1, &i, &j);
929266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  if (hashword(&len, 1, 47) != i)
930266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    printf("hashword2 and hashword mismatch %x %x\n",
931266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	   i, hashword(&len, 1, 47));
932266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
933266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  /* check hashlittle doesn't read before or after the ends of the string */
934266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (h=0, b=buf+1; h<8; ++h, ++b)
935266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
936266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    for (i=0; i<MAXLEN; ++i)
937266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    {
938266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      len = i;
939266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      for (j=0; j<i; ++j) *(b+j)=0;
940266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
941266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      /* these should all be equal */
942266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      ref = hashlittle(b, len, (uint32_t)1);
943266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      *(b+i)=(uint8_t)~0;
944266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      *(b-1)=(uint8_t)~0;
945266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      x = hashlittle(b, len, (uint32_t)1);
946266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      y = hashlittle(b, len, (uint32_t)1);
947266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      if ((ref != x) || (ref != y))
948266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      {
949266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand	printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y,
950266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand               h, i);
951266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand      }
952266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    }
953266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
954266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
955266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
956266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand/* check for problems with nulls */
957266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand void driver4()
958266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
959266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint8_t buf[1];
960266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t h,i,state[HASHSTATE];
961266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
962266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
963266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  buf[0] = ~0;
964266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (i=0; i<HASHSTATE; ++i) state[i] = 1;
965266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("These should all be different\n");
966266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  for (i=0, h=0; i<8; ++i)
967266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  {
968266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    h = hashlittle(buf, 0, h);
969266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand    printf("%2ld  0-byte strings, hash is  %.8x\n", i, h);
970266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  }
971266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
972266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
973266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandvoid driver5()
974266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
975266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  uint32_t b,c;
976266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=0, c=0, hashlittle2("", 0, &c, &b);
977266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* deadbeef deadbeef */
978266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=0xdeadbeef, c=0, hashlittle2("", 0, &c, &b);
979266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* bd5b7dde deadbeef */
980266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=0xdeadbeef, c=0xdeadbeef, hashlittle2("", 0, &c, &b);
981266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* 9c093ccd bd5b7dde */
982266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=0, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
983266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* 17770551 ce7226e6 */
984266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=1, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
985266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* e3607cae bd371de4 */
986266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  b=0, c=1, hashlittle2("Four score and seven years ago", 30, &c, &b);
987266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx %.8lx\n", c, b);   /* cd628161 6cbea4b3 */
988266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  c = hashlittle("Four score and seven years ago", 30, 0);
989266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx\n", c);   /* 17770551 */
990266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  c = hashlittle("Four score and seven years ago", 30, 1);
991266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  printf("hash is %.8lx\n", c);   /* cd628161 */
992266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
993266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
994266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
995266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchandint main()
996266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand{
997266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  driver1();   /* test that the key is hashed: used for timings */
998266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  driver2();   /* test that whole key is hashed thoroughly */
999266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  driver3();   /* test that nothing but the key is hashed */
1000266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  driver4();   /* test hashing multiple buffers (all buffers are null) */
1001266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  driver5();   /* test the hash against known vectors */
1002266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand  return 1;
1003266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand}
1004266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand
1005266dde27811b78f466702295ba0173b8d8be5adaRom Lemarchand#endif  /* SELF_TEST */
1006