blob: bc4996c5e79c1891ea952098cfd9ada183f93f2c [file] [log] [blame]
tanjent@gmail.comf67ce942011-03-14 09:11:18 +00001#include "Platform.h"
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +00002#include "Hashes.h"
tanjent@gmail.comad4b3632010-11-05 01:20:58 +00003#include "KeysetTest.h"
4#include "SpeedTest.h"
5#include "AvalancheTest.h"
6#include "DifferentialTest.h"
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00007
tanjent@gmail.comf67ce942011-03-14 09:11:18 +00008#include <stdio.h>
tanjent@gmail.comad4b3632010-11-05 01:20:58 +00009#include <time.h>
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000010
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000011//-----------------------------------------------------------------------------
12// Configuration. TODO - move these to command-line flags
13
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000014bool g_testAll = false;
15
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000016bool g_testSanity = false;
17bool g_testSpeed = false;
18bool g_testDiff = false;
tanjent@gmail.com623590d2011-03-28 18:19:31 +000019bool g_testDiffDist = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000020bool g_testAvalanche = false;
tanjent@gmail.com623590d2011-03-28 18:19:31 +000021bool g_testBIC = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000022bool g_testCyclic = false;
tanjent@gmail.com96601f22011-03-31 02:41:29 +000023bool g_testTwoBytes = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000024bool g_testSparse = false;
25bool g_testPermutation = false;
26bool g_testWindow = false;
27bool g_testText = false;
28bool g_testZeroes = false;
29bool g_testSeed = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000030
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000031//-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000032// This is the list of all hashes that SMHasher can test.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000033
34struct HashInfo
35{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000036 pfHash hash;
37 int hashbits;
38 uint32_t verification;
39 const char * name;
40 const char * desc;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000041};
42
43HashInfo g_hashes[] =
44{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000045 { DoNothingHash, 32, 0x00000000, "donothing32", "Do-Nothing function (only valid for measuring call overhead)" },
46 { DoNothingHash, 64, 0x00000000, "donothing64", "Do-Nothing function (only valid for measuring call overhead)" },
47 { DoNothingHash, 128, 0x00000000, "donothing128", "Do-Nothing function (only valid for measuring call overhead)" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000048
tanjent@gmail.com623590d2011-03-28 18:19:31 +000049 { crc32, 32, 0x3719DB20, "crc32", "CRC-32" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000050
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000051 { md5_32, 32, 0xC10C356B, "md5_32a", "MD5, first 32 bits of result" },
52 { sha1_32a, 32, 0xF9376EA7, "sha1_32a", "SHA1, first 32 bits of result" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000053
tanjent@gmail.com623590d2011-03-28 18:19:31 +000054 { FNV, 32, 0xE3CBBE91, "FNV", "Fowler-Noll-Vo hash, 32-bit" },
55 { lookup3_test, 32, 0x3D83917A, "lookup3", "Bob Jenkins' lookup3" },
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000056 { SuperFastHash, 32, 0x980ACD1D, "superfast", "Paul Hsieh's SuperFastHash" },
tanjent@gmail.com623590d2011-03-28 18:19:31 +000057 { MurmurOAAT_test, 32, 0x5363BD98, "MurmurOAAT", "Murmur one-at-a-time" },
58 { Crap8_test, 32, 0x743E97A1, "Crap8", "Crap8" },
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000059
60 // MurmurHash2
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000061
tanjent@gmail.com623590d2011-03-28 18:19:31 +000062 { MurmurHash2_test, 32, 0x27864C1E, "Murmur2", "MurmurHash2 for x86, 32-bit" },
63 { MurmurHash2A_test, 32, 0x7FBD4396, "Murmur2A", "MurmurHash2A for x86, 32-bit" },
64 { MurmurHash64A_test, 64, 0x1F0D3804, "Murmur2B", "MurmurHash2 for x64, 64-bit" },
65 { MurmurHash64B_test, 64, 0xDD537C05, "Murmur2C", "MurmurHash2 for x86, 64-bit" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000066
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000067 // MurmurHash3
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000068
tanjent@gmail.com623590d2011-03-28 18:19:31 +000069 { MurmurHash3_x86_32, 32, 0xEA5DFD02, "Murmur3A", "MurmurHash3 for x86, 32-bit" },
70 { MurmurHash3_x86_128, 128, 0x411C981B, "Murmur3C", "MurmurHash3 for x86, 128-bit" },
71 { MurmurHash3_x64_128, 128, 0x04D005BA, "Murmur3F", "MurmurHash3 for x64, 128-bit" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000072
73};
74
75HashInfo * findHash ( const char * name )
76{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000077 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
78 {
79 if(_stricmp(name,g_hashes[i].name) == 0) return &g_hashes[i];
80 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000081
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000082 return NULL;
83}
84
85//-----------------------------------------------------------------------------
86// Self-test on startup - verify that all installed hashes work correctly.
87
88void SelfTest ( void )
89{
90 bool pass = true;
91
92 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
93 {
94 HashInfo * info = & g_hashes[i];
95
96 pass &= VerificationTest(info->hash,info->hashbits,info->verification,false);
97 }
98
99 if(!pass)
100 {
101 printf("Self-test FAILED!\n");
102
103 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
104 {
105 HashInfo * info = & g_hashes[i];
106
107 pass &= VerificationTest(info->hash,info->hashbits,info->verification,true);
108 }
109
110 exit(1);
111 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000112}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000113
114//----------------------------------------------------------------------------
115
116template < typename hashtype >
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000117void test ( hashfunc<hashtype> hash, HashInfo * info )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000118{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000119 const int hashbits = sizeof(hashtype) * 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000120
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000121 printf("-------------------------------------------------------------------------------\n");
122 printf("--- Testing %s\n\n",info->name);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000123
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000124 //-----------------------------------------------------------------------------
125 // Sanity tests
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000126
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000127 if(g_testSanity || g_testAll)
128 {
129 printf("[[[ Sanity Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000130
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000131 VerificationTest(hash,hashbits,info->verification,true);
132 SanityTest(hash,hashbits);
133 AppendedZeroesTest(hash,hashbits);
134 printf("\n");
135 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000136
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000137 //-----------------------------------------------------------------------------
138 // Speed tests
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000139
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000140 if(g_testSpeed || g_testAll)
141 {
142 printf("[[[ Speed Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000143
aappleby@google.com7f20a312011-03-21 20:55:06 +0000144 BulkSpeedTest(info->hash,info->verification);
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000145 printf("\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000146
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000147 for(int i = 1; i < 32; i++)
148 {
149 double cycles;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000150
aappleby@google.com7f20a312011-03-21 20:55:06 +0000151 TinySpeedTest(hashfunc<hashtype>(info->hash),sizeof(hashtype),i,info->verification,true,cycles);
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000152 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000153
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000154 printf("\n");
155 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000156
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000157 //-----------------------------------------------------------------------------
158 // Differential tests
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000159
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000160 if(g_testDiff || g_testAll)
161 {
162 printf("[[[ Differential Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000163
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000164 bool result = true;
165 bool dumpCollisions = false;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000166
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000167 result &= DiffTest< Blob<64>, hashtype >(hash,5,1000,dumpCollisions);
168 result &= DiffTest< Blob<128>, hashtype >(hash,4,1000,dumpCollisions);
169 result &= DiffTest< Blob<256>, hashtype >(hash,3,1000,dumpCollisions);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000170
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000171 if(!result) printf("*********FAIL*********\n");
172 printf("\n");
173 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000174
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000175 //-----------------------------------------------------------------------------
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000176 // Differential-distribution tests
177
178 if(g_testDiffDist /*|| g_testAll*/)
179 {
180 printf("[[[ Differential Distribution Tests ]]]\n\n");
181
182 bool result = true;
183
184 result &= DiffDistTest2<uint64_t,hashtype>(hash);
185
186 printf("\n");
187 }
188
189 //-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000190 // Avalanche tests
191
192 if(g_testAvalanche || g_testAll)
193 {
194 printf("[[[ Avalanche Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000195
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000196 bool result = true;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000197
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000198 result &= AvalancheTest< Blob< 32>, hashtype > (hash,300000);
199 result &= AvalancheTest< Blob< 40>, hashtype > (hash,300000);
200 result &= AvalancheTest< Blob< 48>, hashtype > (hash,300000);
201 result &= AvalancheTest< Blob< 56>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000202
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000203 result &= AvalancheTest< Blob< 64>, hashtype > (hash,300000);
204 result &= AvalancheTest< Blob< 72>, hashtype > (hash,300000);
205 result &= AvalancheTest< Blob< 80>, hashtype > (hash,300000);
206 result &= AvalancheTest< Blob< 88>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000207
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000208 result &= AvalancheTest< Blob< 96>, hashtype > (hash,300000);
209 result &= AvalancheTest< Blob<104>, hashtype > (hash,300000);
210 result &= AvalancheTest< Blob<112>, hashtype > (hash,300000);
211 result &= AvalancheTest< Blob<120>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000212
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000213 result &= AvalancheTest< Blob<128>, hashtype > (hash,300000);
214 result &= AvalancheTest< Blob<136>, hashtype > (hash,300000);
215 result &= AvalancheTest< Blob<144>, hashtype > (hash,300000);
216 result &= AvalancheTest< Blob<152>, hashtype > (hash,300000);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000217
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000218 if(!result) printf("*********FAIL*********\n");
219 printf("\n");
220 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000221
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000222 //-----------------------------------------------------------------------------
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000223 // Bit Independence Criteria
224
225 if(g_testBIC /*|| g_testAll*/)
226 {
227 printf("[[[ Bit Independence Criteria ]]]\n\n");
228
229 bool result = true;
230
231 //result &= BicTest<uint64_t,hashtype>(hash,2000000);
232 BicTest3<Blob<88>,hashtype>(hash,2000000);
233
234 if(!result) printf("*********FAIL*********\n");
235 printf("\n");
236 }
237
238 //-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000239 // Keyset 'Cyclic'
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000240
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000241 if(g_testCyclic || g_testAll)
242 {
243 printf("[[[ Keyset 'Cyclic' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000244
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000245 bool result = true;
246 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000247
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000248 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,10000000,drawDiagram);
249 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+1,8,10000000,drawDiagram);
250 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+2,8,10000000,drawDiagram);
251 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+3,8,10000000,drawDiagram);
252 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+4,8,10000000,drawDiagram);
253
254 if(!result) printf("*********FAIL*********\n");
255 printf("\n");
256 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000257
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000258 //-----------------------------------------------------------------------------
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000259 // Keyset 'TwoBytes'
260
261 if(g_testTwoBytes)
262 {
263 printf("[[[ Keyset 'TwoBytes' Tests ]]]\n\n");
264
265 bool result = true;
266 bool drawDiagram = false;
267
268 result &= TwoBytesTest<hashtype>(hash,24,drawDiagram);
269
270 if(!result) printf("*********FAIL*********\n");
271 printf("\n");
272 }
273
274 //-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000275 // Keyset 'Sparse'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000276
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000277 if(g_testSparse || g_testAll)
278 {
279 printf("[[[ Keyset 'Sparse' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000280
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000281 bool result = true;
282 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000283
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000284 result &= SparseKeyTest< 32,hashtype>(hash,6,true,true,true,drawDiagram);
285 result &= SparseKeyTest< 40,hashtype>(hash,6,true,true,true,drawDiagram);
286 result &= SparseKeyTest< 48,hashtype>(hash,5,true,true,true,drawDiagram);
287 result &= SparseKeyTest< 56,hashtype>(hash,5,true,true,true,drawDiagram);
288 result &= SparseKeyTest< 64,hashtype>(hash,5,true,true,true,drawDiagram);
289 result &= SparseKeyTest< 96,hashtype>(hash,4,true,true,true,drawDiagram);
290 result &= SparseKeyTest< 256,hashtype>(hash,3,true,true,true,drawDiagram);
291 result &= SparseKeyTest<2048,hashtype>(hash,2,true,true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000292
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000293 if(!result) printf("*********FAIL*********\n");
294 printf("\n");
295 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000296
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000297 //-----------------------------------------------------------------------------
298 // Keyset 'Permutation'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000299
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000300 if(g_testPermutation || g_testAll)
301 {
302 {
303 // This one breaks lookup3, surprisingly
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000304
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000305 printf("[[[ Keyset 'Combination Lowbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000306
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000307 bool result = true;
308 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000309
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000310 uint32_t blocks[] =
311 {
312 0x00000000,
313
314 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
315 };
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000316
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000317 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000318
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000319 if(!result) printf("*********FAIL*********\n");
320 printf("\n");
321 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000322
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000323 {
324 printf("[[[ Keyset 'Combination Highbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000325
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000326 bool result = true;
327 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000328
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000329 uint32_t blocks[] =
330 {
331 0x00000000,
332
333 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000
334 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000335
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000336 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000337
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000338 if(!result) printf("*********FAIL*********\n");
339 printf("\n");
340 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000341
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000342 {
343 printf("[[[ Keyset 'Combination 0x8000000' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000344
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000345 bool result = true;
346 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000347
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000348 uint32_t blocks[] =
349 {
350 0x00000000,
351
352 0x80000000,
353 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000354
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000355 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000356
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000357 if(!result) printf("*********FAIL*********\n");
358 printf("\n");
359 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000360
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000361 {
362 printf("[[[ Keyset 'Combination 0x0000001' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000363
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000364 bool result = true;
365 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000366
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000367 uint32_t blocks[] =
368 {
369 0x00000000,
370
371 0x00000001,
372 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000373
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000374 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000375
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000376 if(!result) printf("*********FAIL*********\n");
377 printf("\n");
378 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000379
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000380 {
381 printf("[[[ Keyset 'Combination Hi-Lo' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000382
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000383 bool result = true;
384 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000385
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000386 uint32_t blocks[] =
387 {
388 0x00000000,
389
390 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000391
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000392 0x80000000, 0x40000000, 0xC0000000, 0x20000000, 0xA0000000, 0x60000000, 0xE0000000
393 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000394
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000395 result &= CombinationKeyTest<hashtype>(hash,6,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000396
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000397 if(!result) printf("*********FAIL*********\n");
398 printf("\n");
399 }
400 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000401
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000402 //-----------------------------------------------------------------------------
403 // Keyset 'Window'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000404
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000405 // Skip distribution test for these - they're too easy to distribute well,
406 // and it generates a _lot_ of testing
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000407
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000408 if(g_testWindow || g_testAll)
409 {
410 printf("[[[ Keyset 'Window' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000411
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000412 bool result = true;
413 bool testCollision = true;
414 bool testDistribution = false;
415 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000416
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000417 result &= WindowedKeyTest< Blob<hashbits*2>, hashtype > ( hash, 20, testCollision, testDistribution, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000418
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000419 if(!result) printf("*********FAIL*********\n");
420 printf("\n");
421 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000422
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000423 //-----------------------------------------------------------------------------
424 // Keyset 'Text'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000425
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000426 if(g_testText || g_testAll)
427 {
428 printf("[[[ Keyset 'Text' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000429
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000430 bool result = true;
431 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000432
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000433 const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000434
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000435 result &= TextKeyTest( hash, "Foo", alnum,4, "Bar", drawDiagram );
436 result &= TextKeyTest( hash, "FooBar", alnum,4, "", drawDiagram );
437 result &= TextKeyTest( hash, "", alnum,4, "FooBar", drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000438
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000439 if(!result) printf("*********FAIL*********\n");
440 printf("\n");
441 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000442
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000443 //-----------------------------------------------------------------------------
444 // Keyset 'Zeroes'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000445
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000446 if(g_testZeroes || g_testAll)
447 {
448 printf("[[[ Keyset 'Zeroes' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000449
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000450 bool result = true;
451 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000452
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000453 result &= ZeroKeyTest<hashtype>( hash, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000454
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000455 if(!result) printf("*********FAIL*********\n");
456 printf("\n");
457 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000458
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000459 //-----------------------------------------------------------------------------
460 // Keyset 'Seed'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000461
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000462 if(g_testSeed || g_testAll)
463 {
464 printf("[[[ Keyset 'Seed' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000465
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000466 bool result = true;
467 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000468
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000469 result &= SeedTest<hashtype>( hash, 1000000, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000470
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000471 if(!result) printf("*********FAIL*********\n");
472 printf("\n");
473 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000474}
475
476//-----------------------------------------------------------------------------
477
aappleby@google.com7f20a312011-03-21 20:55:06 +0000478uint32_t g_inputVCode = 1;
479uint32_t g_outputVCode = 1;
480uint32_t g_resultVCode = 1;
481
482HashInfo * g_hashUnderTest = NULL;
483
484void VerifyHash ( const void * key, int len, uint32_t seed, void * out )
485{
486 g_inputVCode = MurmurOAAT(key,len,g_inputVCode);
487 g_inputVCode = MurmurOAAT(&seed,sizeof(uint32_t),g_inputVCode);
488
489 g_hashUnderTest->hash(key,len,seed,out);
490
491 g_outputVCode = MurmurOAAT(out,g_hashUnderTest->hashbits/8,g_outputVCode);
492}
493
494//-----------------------------------------------------------------------------
495
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000496void testHash ( const char * name )
497{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000498 HashInfo * pInfo = findHash(name);
aappleby@google.com7f20a312011-03-21 20:55:06 +0000499
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000500 if(pInfo == NULL)
501 {
502 printf("Invalid hash '%s' specified\n",name);
503 return;
504 }
505 else
506 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000507 g_hashUnderTest = pInfo;
508
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000509 if(pInfo->hashbits == 32)
510 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000511 test<uint32_t>( VerifyHash, pInfo );
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000512 }
513 else if(pInfo->hashbits == 64)
514 {
515 test<uint64_t>( pInfo->hash, pInfo );
516 }
517 else if(pInfo->hashbits == 128)
518 {
519 test<uint128_t>( pInfo->hash, pInfo );
520 }
521 else if(pInfo->hashbits == 256)
522 {
523 test<uint256_t>( pInfo->hash, pInfo );
524 }
525 else
526 {
527 printf("Invalid hash bit width %d for hash '%s'",pInfo->hashbits,pInfo->name);
528 }
529 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000530}
531//-----------------------------------------------------------------------------
532
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000533int main ( int argc, char ** argv )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000534{
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000535 const char * hashToTest = "murmur3a";
536
aappleby@google.com7f20a312011-03-21 20:55:06 +0000537 if(argc < 2)
538 {
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000539 printf("(No test hash given on command line, testing Murmur3_x86_32.)\n");
540 }
541 else
542 {
543 hashToTest = argv[1];
aappleby@google.com7f20a312011-03-21 20:55:06 +0000544 }
545
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000546 SetAffinity(2);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000547
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000548 SelfTest();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000549
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000550 int timeBegin = clock();
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000551
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000552 g_testAll = true;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000553
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000554 //g_testSanity = true;
555 //g_testSpeed = true;
aappleby@google.com7f20a312011-03-21 20:55:06 +0000556 //g_testAvalanche = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000557 //g_testBIC = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000558 //g_testCyclic = true;
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000559 //g_testTwoBytes = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000560 //g_testDiff = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000561 //g_testDiffDist = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000562 //g_testSparse = true;
563 //g_testPermutation = true;
564 //g_testZeroes = true;
tanjent@gmail.com31a9e8e2010-11-09 20:29:19 +0000565
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000566 testHash(hashToTest);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000567
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000568 /*
569 for(int i = 0; i < sizeof(g_hashes)/sizeof(HashInfo); i++)
570 {
571 testHash(g_hashes[i].name);
572 }
573 */
574
575 //testHash("murmur3a");
576 //testHash("murmur3c");
577 //testHash("murmur3f");
578
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000579 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000580
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000581 int timeEnd = clock();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000582
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000583 printf("\n");
aappleby@google.com7f20a312011-03-21 20:55:06 +0000584 printf("Input vcode 0x%08x, Output vcode 0x%08x, Result vcode 0x%08x\n",g_inputVCode,g_outputVCode,g_resultVCode);
tanjent@gmail.com3ee45612011-03-21 19:33:01 +0000585 printf("Verification value is 0x%08x - Testing took %f seconds\n",g_verify,double(timeEnd-timeBegin)/double(CLOCKS_PER_SEC));
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000586 printf("-------------------------------------------------------------------------------\n");
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000587 return 0;
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000588}