blob: 5f8921f32fbdcd2ddea183dc90cd46b82ba53078 [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.com603c8782011-04-01 08:50:06 +000069 { MurmurHash3_x86_32, 32, 0xCB75A3F6, "Murmur3A", "MurmurHash3 for x86, 32-bit" },
tanjent@gmail.comb93e1c52011-04-01 21:41:17 +000070 { MurmurHash3_x86_128, 128, 0x917EC4EF, "Murmur3C", "MurmurHash3 for x86, 128-bit" },
tanjent@gmail.com99155972011-04-02 00:50:27 +000071 { MurmurHash3_x64_128, 128, 0x9E20536F, "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.com603c8782011-04-01 08:50:06 +0000223 // Bit Independence Criteria. Interesting, but doesn't tell us much about
224 // collision or distribution.
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000225
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000226 if(g_testBIC)
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000227 {
228 printf("[[[ Bit Independence Criteria ]]]\n\n");
229
230 bool result = true;
231
232 //result &= BicTest<uint64_t,hashtype>(hash,2000000);
233 BicTest3<Blob<88>,hashtype>(hash,2000000);
234
235 if(!result) printf("*********FAIL*********\n");
236 printf("\n");
237 }
238
239 //-----------------------------------------------------------------------------
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000240 // Keyset 'Cyclic' - keys of the form "abcdabcdabcd..."
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000241
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000242 if(g_testCyclic || g_testAll)
243 {
244 printf("[[[ Keyset 'Cyclic' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000245
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000246 bool result = true;
247 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000248
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000249 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,10000000,drawDiagram);
250 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+1,8,10000000,drawDiagram);
251 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+2,8,10000000,drawDiagram);
252 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+3,8,10000000,drawDiagram);
253 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+4,8,10000000,drawDiagram);
254
255 if(!result) printf("*********FAIL*********\n");
256 printf("\n");
257 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000258
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000259 //-----------------------------------------------------------------------------
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000260 // Keyset 'TwoBytes' - all keys up to N bytes containing two non-zero bytes
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000261
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000262 // This generates some huge keysets, 128-bit tests will take ~1.3 gigs of RAM.
263
264 if(g_testTwoBytes || g_testAll)
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000265 {
266 printf("[[[ Keyset 'TwoBytes' Tests ]]]\n\n");
267
268 bool result = true;
269 bool drawDiagram = false;
270
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000271 for(int i = 4; i <= 20; i += 4)
272 {
273 result &= TwoBytesTest2<hashtype>(hash,i,drawDiagram);
274 }
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000275
276 if(!result) printf("*********FAIL*********\n");
277 printf("\n");
278 }
279
280 //-----------------------------------------------------------------------------
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000281 // Keyset 'Sparse' - keys with all bits 0 except a few
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000282
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000283 if(g_testSparse || g_testAll)
284 {
285 printf("[[[ Keyset 'Sparse' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000286
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000287 bool result = true;
288 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000289
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000290 result &= SparseKeyTest< 32,hashtype>(hash,6,true,true,true,drawDiagram);
291 result &= SparseKeyTest< 40,hashtype>(hash,6,true,true,true,drawDiagram);
292 result &= SparseKeyTest< 48,hashtype>(hash,5,true,true,true,drawDiagram);
293 result &= SparseKeyTest< 56,hashtype>(hash,5,true,true,true,drawDiagram);
294 result &= SparseKeyTest< 64,hashtype>(hash,5,true,true,true,drawDiagram);
295 result &= SparseKeyTest< 96,hashtype>(hash,4,true,true,true,drawDiagram);
296 result &= SparseKeyTest< 256,hashtype>(hash,3,true,true,true,drawDiagram);
297 result &= SparseKeyTest<2048,hashtype>(hash,2,true,true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000298
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000299 if(!result) printf("*********FAIL*********\n");
300 printf("\n");
301 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000302
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000303 //-----------------------------------------------------------------------------
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000304 // Keyset 'Permutation' - all possible combinations of a set of blocks
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000305
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000306 if(g_testPermutation || g_testAll)
307 {
308 {
309 // This one breaks lookup3, surprisingly
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000310
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000311 printf("[[[ Keyset 'Combination Lowbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000312
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000313 bool result = true;
314 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000315
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000316 uint32_t blocks[] =
317 {
318 0x00000000,
319
320 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
321 };
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000322
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000323 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000324
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000325 if(!result) printf("*********FAIL*********\n");
326 printf("\n");
327 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000328
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000329 {
330 printf("[[[ Keyset 'Combination Highbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000331
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000332 bool result = true;
333 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000334
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000335 uint32_t blocks[] =
336 {
337 0x00000000,
338
339 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000
340 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000341
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000342 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000343
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000344 if(!result) printf("*********FAIL*********\n");
345 printf("\n");
346 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000347
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000348 {
349 printf("[[[ Keyset 'Combination 0x8000000' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000350
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000351 bool result = true;
352 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000353
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000354 uint32_t blocks[] =
355 {
356 0x00000000,
357
358 0x80000000,
359 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000360
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000361 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000362
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000363 if(!result) printf("*********FAIL*********\n");
364 printf("\n");
365 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000366
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000367 {
368 printf("[[[ Keyset 'Combination 0x0000001' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000369
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000370 bool result = true;
371 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000372
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000373 uint32_t blocks[] =
374 {
375 0x00000000,
376
377 0x00000001,
378 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000379
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000380 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000381
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000382 if(!result) printf("*********FAIL*********\n");
383 printf("\n");
384 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000385
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000386 {
387 printf("[[[ Keyset 'Combination Hi-Lo' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000388
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000389 bool result = true;
390 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000391
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000392 uint32_t blocks[] =
393 {
394 0x00000000,
395
396 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000397
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000398 0x80000000, 0x40000000, 0xC0000000, 0x20000000, 0xA0000000, 0x60000000, 0xE0000000
399 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000400
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000401 result &= CombinationKeyTest<hashtype>(hash,6,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000402
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000403 if(!result) printf("*********FAIL*********\n");
404 printf("\n");
405 }
406 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000407
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000408 //-----------------------------------------------------------------------------
409 // Keyset 'Window'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000410
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000411 // Skip distribution test for these - they're too easy to distribute well,
412 // and it generates a _lot_ of testing
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000413
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000414 if(g_testWindow || g_testAll)
415 {
416 printf("[[[ Keyset 'Window' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000417
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000418 bool result = true;
419 bool testCollision = true;
420 bool testDistribution = false;
421 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000422
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000423 result &= WindowedKeyTest< Blob<hashbits*2>, hashtype > ( hash, 20, testCollision, testDistribution, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000424
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000425 if(!result) printf("*********FAIL*********\n");
426 printf("\n");
427 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000428
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000429 //-----------------------------------------------------------------------------
430 // Keyset 'Text'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000431
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000432 if(g_testText || g_testAll)
433 {
434 printf("[[[ Keyset 'Text' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000435
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000436 bool result = true;
437 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000438
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000439 const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000440
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000441 result &= TextKeyTest( hash, "Foo", alnum,4, "Bar", drawDiagram );
442 result &= TextKeyTest( hash, "FooBar", alnum,4, "", drawDiagram );
443 result &= TextKeyTest( hash, "", alnum,4, "FooBar", drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000444
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000445 if(!result) printf("*********FAIL*********\n");
446 printf("\n");
447 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000448
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000449 //-----------------------------------------------------------------------------
450 // Keyset 'Zeroes'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000451
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000452 if(g_testZeroes || g_testAll)
453 {
454 printf("[[[ Keyset 'Zeroes' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000455
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000456 bool result = true;
457 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000458
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000459 result &= ZeroKeyTest<hashtype>( hash, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000460
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000461 if(!result) printf("*********FAIL*********\n");
462 printf("\n");
463 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000464
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000465 //-----------------------------------------------------------------------------
466 // Keyset 'Seed'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000467
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000468 if(g_testSeed || g_testAll)
469 {
470 printf("[[[ Keyset 'Seed' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000471
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000472 bool result = true;
473 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000474
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000475 result &= SeedTest<hashtype>( hash, 1000000, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000476
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000477 if(!result) printf("*********FAIL*********\n");
478 printf("\n");
479 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000480}
481
482//-----------------------------------------------------------------------------
483
aappleby@google.com7f20a312011-03-21 20:55:06 +0000484uint32_t g_inputVCode = 1;
485uint32_t g_outputVCode = 1;
486uint32_t g_resultVCode = 1;
487
488HashInfo * g_hashUnderTest = NULL;
489
490void VerifyHash ( const void * key, int len, uint32_t seed, void * out )
491{
492 g_inputVCode = MurmurOAAT(key,len,g_inputVCode);
493 g_inputVCode = MurmurOAAT(&seed,sizeof(uint32_t),g_inputVCode);
494
495 g_hashUnderTest->hash(key,len,seed,out);
496
497 g_outputVCode = MurmurOAAT(out,g_hashUnderTest->hashbits/8,g_outputVCode);
498}
499
500//-----------------------------------------------------------------------------
501
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000502void testHash ( const char * name )
503{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000504 HashInfo * pInfo = findHash(name);
aappleby@google.com7f20a312011-03-21 20:55:06 +0000505
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000506 if(pInfo == NULL)
507 {
508 printf("Invalid hash '%s' specified\n",name);
509 return;
510 }
511 else
512 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000513 g_hashUnderTest = pInfo;
514
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000515 if(pInfo->hashbits == 32)
516 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000517 test<uint32_t>( VerifyHash, pInfo );
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000518 }
519 else if(pInfo->hashbits == 64)
520 {
521 test<uint64_t>( pInfo->hash, pInfo );
522 }
523 else if(pInfo->hashbits == 128)
524 {
525 test<uint128_t>( pInfo->hash, pInfo );
526 }
527 else if(pInfo->hashbits == 256)
528 {
529 test<uint256_t>( pInfo->hash, pInfo );
530 }
531 else
532 {
533 printf("Invalid hash bit width %d for hash '%s'",pInfo->hashbits,pInfo->name);
534 }
535 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000536}
537//-----------------------------------------------------------------------------
538
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000539int main ( int argc, char ** argv )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000540{
tanjent@gmail.comb93e1c52011-04-01 21:41:17 +0000541 const char * hashToTest = "murmur3f";
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000542
aappleby@google.com7f20a312011-03-21 20:55:06 +0000543 if(argc < 2)
544 {
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000545 printf("(No test hash given on command line, testing Murmur3_x86_32.)\n");
546 }
547 else
548 {
549 hashToTest = argv[1];
aappleby@google.com7f20a312011-03-21 20:55:06 +0000550 }
551
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000552 SetAffinity(3);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000553
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000554 SelfTest();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000555
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000556 int timeBegin = clock();
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000557
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000558 g_testAll = true;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000559
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000560 //g_testSanity = true;
561 //g_testSpeed = true;
aappleby@google.com7f20a312011-03-21 20:55:06 +0000562 //g_testAvalanche = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000563 //g_testBIC = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000564 //g_testCyclic = true;
tanjent@gmail.com96601f22011-03-31 02:41:29 +0000565 //g_testTwoBytes = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000566 //g_testDiff = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000567 //g_testDiffDist = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000568 //g_testSparse = true;
569 //g_testPermutation = true;
tanjent@gmail.com603c8782011-04-01 08:50:06 +0000570 //g_testWindow = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000571 //g_testZeroes = true;
tanjent@gmail.com31a9e8e2010-11-09 20:29:19 +0000572
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000573 testHash(hashToTest);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000574
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000575 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000576
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000577 int timeEnd = clock();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000578
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000579 printf("\n");
aappleby@google.com7f20a312011-03-21 20:55:06 +0000580 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 +0000581 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 +0000582 printf("-------------------------------------------------------------------------------\n");
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000583 return 0;
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000584}