blob: 36a6c9639f1fb8de456adeff34e67477c2739847 [file] [log] [blame]
tanjent@gmail.comf3b78972012-03-01 03:38:55 +00001#include "Hashes.h"
2
3#include "Random.h"
4
5
6#include <stdlib.h>
7//#include <stdint.h>
8#include <assert.h>
9//#include <emmintrin.h>
10//#include <xmmintrin.h>
11
12//----------------------------------------------------------------------------
13// fake / bad hashes
14
15void BadHash ( const void * key, int len, uint32_t seed, void * out )
16{
17 uint32_t h = seed;
18
19 const uint8_t * data = (const uint8_t*)key;
20
21 for(int i = 0; i < len; i++)
22 {
23 h ^= h >> 3;
24 h ^= h << 5;
25 h ^= data[i];
26 }
27
28 *(uint32_t*)out = h;
29}
30
31void sumhash ( const void * key, int len, uint32_t seed, void * out )
32{
33 uint32_t h = seed;
34
35 const uint8_t * data = (const uint8_t*)key;
36
37 for(int i = 0; i < len; i++)
38 {
39 h += data[i];
40 }
41
42 *(uint32_t*)out = h;
43}
44
45void sumhash32 ( const void * key, int len, uint32_t seed, void * out )
46{
47 uint32_t h = seed;
48
49 const uint32_t * data = (const uint32_t*)key;
50
51 for(int i = 0; i < len/4; i++)
52 {
53 h += data[i];
54 }
55
56 *(uint32_t*)out = h;
57}
58
59void DoNothingHash ( const void *, int, uint32_t, void * )
60{
61}
62
63//-----------------------------------------------------------------------------
64// One-byte-at-a-time hash based on Murmur's mix
65
66uint32_t MurmurOAAT ( const void * key, int len, uint32_t seed )
67{
68 const uint8_t * data = (const uint8_t*)key;
69
70 uint32_t h = seed;
71
72 for(int i = 0; i < len; i++)
73 {
74 h ^= data[i];
75 h *= 0x5bd1e995;
76 h ^= h >> 15;
77 }
78
79 return h;
80}
81
82void MurmurOAAT_test ( const void * key, int len, uint32_t seed, void * out )
83{
84 *(uint32_t*)out = MurmurOAAT(key,len,seed);
85}
86
87//----------------------------------------------------------------------------
88
89void FNV ( const void * key, int len, uint32_t seed, void * out )
90{
91 unsigned int h = seed;
92
93 const uint8_t * data = (const uint8_t*)key;
94
95 h ^= BIG_CONSTANT(2166136261);
96
97 for(int i = 0; i < len; i++)
98 {
99 h ^= data[i];
100 h *= 16777619;
101 }
102
103 *(uint32_t*)out = h;
104}
105
106//-----------------------------------------------------------------------------
107
108uint32_t x17 ( const void * key, int len, uint32_t h )
109{
110 const uint8_t * data = (const uint8_t*)key;
111
112 for(int i = 0; i < len; ++i)
113 {
114 h = 17 * h + (data[i] - ' ');
115 }
116
117 return h ^ (h >> 16);
118}
119
120//-----------------------------------------------------------------------------
121
122void Bernstein ( const void * key, int len, uint32_t seed, void * out )
123{
124 const uint8_t * data = (const uint8_t*)key;
125
126 for(int i = 0; i < len; ++i)
127 {
128 seed = 33 * seed + data[i];
129 }
130
131 *(uint32_t*)out = seed;
132}
133
134//-----------------------------------------------------------------------------
135// Crap8 hash from http://www.team5150.com/~andrew/noncryptohashzoo/Crap8.html
136
137uint32_t Crap8( const uint8_t *key, uint32_t len, uint32_t seed ) {
138 #define c8fold( a, b, y, z ) { p = (uint32_t)(a) * (uint64_t)(b); y ^= (uint32_t)p; z ^= (uint32_t)(p >> 32); }
139 #define c8mix( in ) { h *= m; c8fold( in, m, k, h ); }
140
141 const uint32_t m = 0x83d2e73b, n = 0x97e1cc59, *key4 = (const uint32_t *)key;
142 uint32_t h = len + seed, k = n + len;
143 uint64_t p;
144
145 while ( len >= 8 ) { c8mix(key4[0]) c8mix(key4[1]) key4 += 2; len -= 8; }
146 if ( len >= 4 ) { c8mix(key4[0]) key4 += 1; len -= 4; }
147 if ( len ) { c8mix( key4[0] & ( ( 1 << ( len * 8 ) ) - 1 ) ) }
148 c8fold( h ^ k, n, k, k )
149 return k;
150}
151
152void Crap8_test ( const void * key, int len, uint32_t seed, void * out )
153{
154 *(uint32_t*)out = Crap8((const uint8_t*)key,len,seed);
155}