blob: ab397e714b97f006664f5501c65650b9ff0b1544 [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;
23bool g_testSparse = false;
24bool g_testPermutation = false;
25bool g_testWindow = false;
26bool g_testText = false;
27bool g_testZeroes = false;
28bool g_testSeed = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000029
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000030//-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000031// This is the list of all hashes that SMHasher can test.
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000032
33struct HashInfo
34{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000035 pfHash hash;
36 int hashbits;
37 uint32_t verification;
38 const char * name;
39 const char * desc;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000040};
41
42HashInfo g_hashes[] =
43{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000044 { DoNothingHash, 32, 0x00000000, "donothing32", "Do-Nothing function (only valid for measuring call overhead)" },
45 { DoNothingHash, 64, 0x00000000, "donothing64", "Do-Nothing function (only valid for measuring call overhead)" },
46 { DoNothingHash, 128, 0x00000000, "donothing128", "Do-Nothing function (only valid for measuring call overhead)" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000047
tanjent@gmail.com623590d2011-03-28 18:19:31 +000048 { crc32, 32, 0x3719DB20, "crc32", "CRC-32" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000049
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000050 { md5_32, 32, 0xC10C356B, "md5_32a", "MD5, first 32 bits of result" },
51 { sha1_32a, 32, 0xF9376EA7, "sha1_32a", "SHA1, first 32 bits of result" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000052
tanjent@gmail.com623590d2011-03-28 18:19:31 +000053 { FNV, 32, 0xE3CBBE91, "FNV", "Fowler-Noll-Vo hash, 32-bit" },
54 { lookup3_test, 32, 0x3D83917A, "lookup3", "Bob Jenkins' lookup3" },
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000055 { SuperFastHash, 32, 0x980ACD1D, "superfast", "Paul Hsieh's SuperFastHash" },
tanjent@gmail.com623590d2011-03-28 18:19:31 +000056 { MurmurOAAT_test, 32, 0x5363BD98, "MurmurOAAT", "Murmur one-at-a-time" },
57 { Crap8_test, 32, 0x743E97A1, "Crap8", "Crap8" },
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000058
59 // MurmurHash2
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000060
tanjent@gmail.com623590d2011-03-28 18:19:31 +000061 { MurmurHash2_test, 32, 0x27864C1E, "Murmur2", "MurmurHash2 for x86, 32-bit" },
62 { MurmurHash2A_test, 32, 0x7FBD4396, "Murmur2A", "MurmurHash2A for x86, 32-bit" },
63 { MurmurHash64A_test, 64, 0x1F0D3804, "Murmur2B", "MurmurHash2 for x64, 64-bit" },
64 { MurmurHash64B_test, 64, 0xDD537C05, "Murmur2C", "MurmurHash2 for x86, 64-bit" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000065
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000066 // MurmurHash3
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000067
tanjent@gmail.com623590d2011-03-28 18:19:31 +000068 { MurmurHash3_x86_32, 32, 0xEA5DFD02, "Murmur3A", "MurmurHash3 for x86, 32-bit" },
69 { MurmurHash3_x86_128, 128, 0x411C981B, "Murmur3C", "MurmurHash3 for x86, 128-bit" },
70 { MurmurHash3_x64_128, 128, 0x04D005BA, "Murmur3F", "MurmurHash3 for x64, 128-bit" },
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000071
72};
73
74HashInfo * findHash ( const char * name )
75{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000076 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
77 {
78 if(_stricmp(name,g_hashes[i].name) == 0) return &g_hashes[i];
79 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000080
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000081 return NULL;
82}
83
84//-----------------------------------------------------------------------------
85// Self-test on startup - verify that all installed hashes work correctly.
86
87void SelfTest ( void )
88{
89 bool pass = true;
90
91 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
92 {
93 HashInfo * info = & g_hashes[i];
94
95 pass &= VerificationTest(info->hash,info->hashbits,info->verification,false);
96 }
97
98 if(!pass)
99 {
100 printf("Self-test FAILED!\n");
101
102 for(int i = 0; i < sizeof(g_hashes) / sizeof(HashInfo); i++)
103 {
104 HashInfo * info = & g_hashes[i];
105
106 pass &= VerificationTest(info->hash,info->hashbits,info->verification,true);
107 }
108
109 exit(1);
110 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000111}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000112
113//----------------------------------------------------------------------------
114
115template < typename hashtype >
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000116void test ( hashfunc<hashtype> hash, HashInfo * info )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000117{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000118 const int hashbits = sizeof(hashtype) * 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000119
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000120 printf("-------------------------------------------------------------------------------\n");
121 printf("--- Testing %s\n\n",info->name);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000122
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000123 //-----------------------------------------------------------------------------
124 // Sanity tests
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000125
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000126 if(g_testSanity || g_testAll)
127 {
128 printf("[[[ Sanity Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000129
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000130 VerificationTest(hash,hashbits,info->verification,true);
131 SanityTest(hash,hashbits);
132 AppendedZeroesTest(hash,hashbits);
133 printf("\n");
134 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000135
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000136 //-----------------------------------------------------------------------------
137 // Speed tests
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000138
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000139 if(g_testSpeed || g_testAll)
140 {
141 printf("[[[ Speed Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000142
aappleby@google.com7f20a312011-03-21 20:55:06 +0000143 BulkSpeedTest(info->hash,info->verification);
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000144 printf("\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000145
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000146 for(int i = 1; i < 32; i++)
147 {
148 double cycles;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000149
aappleby@google.com7f20a312011-03-21 20:55:06 +0000150 TinySpeedTest(hashfunc<hashtype>(info->hash),sizeof(hashtype),i,info->verification,true,cycles);
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000151 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000152
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000153 printf("\n");
154 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000155
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000156 //-----------------------------------------------------------------------------
157 // Differential tests
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000158
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000159 if(g_testDiff || g_testAll)
160 {
161 printf("[[[ Differential Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000162
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000163 bool result = true;
164 bool dumpCollisions = false;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000165
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000166 result &= DiffTest< Blob<64>, hashtype >(hash,5,1000,dumpCollisions);
167 result &= DiffTest< Blob<128>, hashtype >(hash,4,1000,dumpCollisions);
168 result &= DiffTest< Blob<256>, hashtype >(hash,3,1000,dumpCollisions);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000169
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000170 if(!result) printf("*********FAIL*********\n");
171 printf("\n");
172 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000173
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000174 //-----------------------------------------------------------------------------
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000175 // Differential-distribution tests
176
177 if(g_testDiffDist /*|| g_testAll*/)
178 {
179 printf("[[[ Differential Distribution Tests ]]]\n\n");
180
181 bool result = true;
182
183 result &= DiffDistTest2<uint64_t,hashtype>(hash);
184
185 printf("\n");
186 }
187
188 //-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000189 // Avalanche tests
190
191 if(g_testAvalanche || g_testAll)
192 {
193 printf("[[[ Avalanche Tests ]]]\n\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000194
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000195 bool result = true;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000196
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000197 result &= AvalancheTest< Blob< 32>, hashtype > (hash,300000);
198 result &= AvalancheTest< Blob< 40>, hashtype > (hash,300000);
199 result &= AvalancheTest< Blob< 48>, hashtype > (hash,300000);
200 result &= AvalancheTest< Blob< 56>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000201
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000202 result &= AvalancheTest< Blob< 64>, hashtype > (hash,300000);
203 result &= AvalancheTest< Blob< 72>, hashtype > (hash,300000);
204 result &= AvalancheTest< Blob< 80>, hashtype > (hash,300000);
205 result &= AvalancheTest< Blob< 88>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000206
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000207 result &= AvalancheTest< Blob< 96>, hashtype > (hash,300000);
208 result &= AvalancheTest< Blob<104>, hashtype > (hash,300000);
209 result &= AvalancheTest< Blob<112>, hashtype > (hash,300000);
210 result &= AvalancheTest< Blob<120>, hashtype > (hash,300000);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000211
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000212 result &= AvalancheTest< Blob<128>, hashtype > (hash,300000);
213 result &= AvalancheTest< Blob<136>, hashtype > (hash,300000);
214 result &= AvalancheTest< Blob<144>, hashtype > (hash,300000);
215 result &= AvalancheTest< Blob<152>, hashtype > (hash,300000);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000216
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000217 if(!result) printf("*********FAIL*********\n");
218 printf("\n");
219 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000220
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000221 //-----------------------------------------------------------------------------
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000222 // Bit Independence Criteria
223
224 if(g_testBIC /*|| g_testAll*/)
225 {
226 printf("[[[ Bit Independence Criteria ]]]\n\n");
227
228 bool result = true;
229
230 //result &= BicTest<uint64_t,hashtype>(hash,2000000);
231 BicTest3<Blob<88>,hashtype>(hash,2000000);
232
233 if(!result) printf("*********FAIL*********\n");
234 printf("\n");
235 }
236
237 //-----------------------------------------------------------------------------
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000238 // Keyset 'Cyclic'
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000239
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000240 if(g_testCyclic || g_testAll)
241 {
242 printf("[[[ Keyset 'Cyclic' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000243
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000244 bool result = true;
245 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000246
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000247 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+0,8,10000000,drawDiagram);
248 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+1,8,10000000,drawDiagram);
249 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+2,8,10000000,drawDiagram);
250 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+3,8,10000000,drawDiagram);
251 result &= CyclicKeyTest<hashtype>(hash,sizeof(hashtype)+4,8,10000000,drawDiagram);
252
253 if(!result) printf("*********FAIL*********\n");
254 printf("\n");
255 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000256
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000257 //-----------------------------------------------------------------------------
258 // Keyset 'Sparse'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000259
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000260 if(g_testSparse || g_testAll)
261 {
262 printf("[[[ Keyset 'Sparse' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000263
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000264 bool result = true;
265 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000266
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000267 result &= SparseKeyTest< 32,hashtype>(hash,6,true,true,true,drawDiagram);
268 result &= SparseKeyTest< 40,hashtype>(hash,6,true,true,true,drawDiagram);
269 result &= SparseKeyTest< 48,hashtype>(hash,5,true,true,true,drawDiagram);
270 result &= SparseKeyTest< 56,hashtype>(hash,5,true,true,true,drawDiagram);
271 result &= SparseKeyTest< 64,hashtype>(hash,5,true,true,true,drawDiagram);
272 result &= SparseKeyTest< 96,hashtype>(hash,4,true,true,true,drawDiagram);
273 result &= SparseKeyTest< 256,hashtype>(hash,3,true,true,true,drawDiagram);
274 result &= SparseKeyTest<2048,hashtype>(hash,2,true,true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000275
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000276 if(!result) printf("*********FAIL*********\n");
277 printf("\n");
278 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000279
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000280 //-----------------------------------------------------------------------------
281 // Keyset 'Permutation'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000282
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000283 if(g_testPermutation || g_testAll)
284 {
285 {
286 // This one breaks lookup3, surprisingly
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000287
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000288 printf("[[[ Keyset 'Combination Lowbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000289
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000290 bool result = true;
291 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000292
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000293 uint32_t blocks[] =
294 {
295 0x00000000,
296
297 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
298 };
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000299
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000300 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000301
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000302 if(!result) printf("*********FAIL*********\n");
303 printf("\n");
304 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000305
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000306 {
307 printf("[[[ Keyset 'Combination Highbits' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000308
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000309 bool result = true;
310 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000311
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000312 uint32_t blocks[] =
313 {
314 0x00000000,
315
316 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000
317 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000318
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000319 result &= CombinationKeyTest<hashtype>(hash,8,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000320
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000321 if(!result) printf("*********FAIL*********\n");
322 printf("\n");
323 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000324
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000325 {
326 printf("[[[ Keyset 'Combination 0x8000000' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000327
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000328 bool result = true;
329 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000330
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000331 uint32_t blocks[] =
332 {
333 0x00000000,
334
335 0x80000000,
336 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000337
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000338 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000339
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000340 if(!result) printf("*********FAIL*********\n");
341 printf("\n");
342 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000343
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000344 {
345 printf("[[[ Keyset 'Combination 0x0000001' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000346
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000347 bool result = true;
348 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000349
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000350 uint32_t blocks[] =
351 {
352 0x00000000,
353
354 0x00000001,
355 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000356
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000357 result &= CombinationKeyTest<hashtype>(hash,20,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000358
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000359 if(!result) printf("*********FAIL*********\n");
360 printf("\n");
361 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000362
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000363 {
364 printf("[[[ Keyset 'Combination Hi-Lo' Tests ]]]\n\n");
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000365
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000366 bool result = true;
367 bool drawDiagram = false;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000368
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000369 uint32_t blocks[] =
370 {
371 0x00000000,
372
373 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000374
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000375 0x80000000, 0x40000000, 0xC0000000, 0x20000000, 0xA0000000, 0x60000000, 0xE0000000
376 };
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000377
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000378 result &= CombinationKeyTest<hashtype>(hash,6,blocks,sizeof(blocks) / sizeof(uint32_t),true,true,drawDiagram);
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000379
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000380 if(!result) printf("*********FAIL*********\n");
381 printf("\n");
382 }
383 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000384
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000385 //-----------------------------------------------------------------------------
386 // Keyset 'Window'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000387
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000388 // Skip distribution test for these - they're too easy to distribute well,
389 // and it generates a _lot_ of testing
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000390
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000391 if(g_testWindow || g_testAll)
392 {
393 printf("[[[ Keyset 'Window' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000394
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000395 bool result = true;
396 bool testCollision = true;
397 bool testDistribution = false;
398 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000399
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000400 result &= WindowedKeyTest< Blob<hashbits*2>, hashtype > ( hash, 20, testCollision, testDistribution, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000401
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000402 if(!result) printf("*********FAIL*********\n");
403 printf("\n");
404 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000405
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000406 //-----------------------------------------------------------------------------
407 // Keyset 'Text'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000408
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000409 if(g_testText || g_testAll)
410 {
411 printf("[[[ Keyset 'Text' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000412
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000413 bool result = true;
414 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000415
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000416 const char * alnum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000417
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000418 result &= TextKeyTest( hash, "Foo", alnum,4, "Bar", drawDiagram );
419 result &= TextKeyTest( hash, "FooBar", alnum,4, "", drawDiagram );
420 result &= TextKeyTest( hash, "", alnum,4, "FooBar", drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000421
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000422 if(!result) printf("*********FAIL*********\n");
423 printf("\n");
424 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000425
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000426 //-----------------------------------------------------------------------------
427 // Keyset 'Zeroes'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000428
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000429 if(g_testZeroes || g_testAll)
430 {
431 printf("[[[ Keyset 'Zeroes' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000432
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000433 bool result = true;
434 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000435
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000436 result &= ZeroKeyTest<hashtype>( hash, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000437
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000438 if(!result) printf("*********FAIL*********\n");
439 printf("\n");
440 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000441
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000442 //-----------------------------------------------------------------------------
443 // Keyset 'Seed'
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000444
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000445 if(g_testSeed || g_testAll)
446 {
447 printf("[[[ Keyset 'Seed' Tests ]]]\n\n");
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000448
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000449 bool result = true;
450 bool drawDiagram = false;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000451
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000452 result &= SeedTest<hashtype>( hash, 1000000, drawDiagram );
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000453
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000454 if(!result) printf("*********FAIL*********\n");
455 printf("\n");
456 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000457}
458
459//-----------------------------------------------------------------------------
460
aappleby@google.com7f20a312011-03-21 20:55:06 +0000461uint32_t g_inputVCode = 1;
462uint32_t g_outputVCode = 1;
463uint32_t g_resultVCode = 1;
464
465HashInfo * g_hashUnderTest = NULL;
466
467void VerifyHash ( const void * key, int len, uint32_t seed, void * out )
468{
469 g_inputVCode = MurmurOAAT(key,len,g_inputVCode);
470 g_inputVCode = MurmurOAAT(&seed,sizeof(uint32_t),g_inputVCode);
471
472 g_hashUnderTest->hash(key,len,seed,out);
473
474 g_outputVCode = MurmurOAAT(out,g_hashUnderTest->hashbits/8,g_outputVCode);
475}
476
477//-----------------------------------------------------------------------------
478
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000479void testHash ( const char * name )
480{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000481 HashInfo * pInfo = findHash(name);
aappleby@google.com7f20a312011-03-21 20:55:06 +0000482
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000483 if(pInfo == NULL)
484 {
485 printf("Invalid hash '%s' specified\n",name);
486 return;
487 }
488 else
489 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000490 g_hashUnderTest = pInfo;
491
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000492 if(pInfo->hashbits == 32)
493 {
aappleby@google.com7f20a312011-03-21 20:55:06 +0000494 test<uint32_t>( VerifyHash, pInfo );
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000495 }
496 else if(pInfo->hashbits == 64)
497 {
498 test<uint64_t>( pInfo->hash, pInfo );
499 }
500 else if(pInfo->hashbits == 128)
501 {
502 test<uint128_t>( pInfo->hash, pInfo );
503 }
504 else if(pInfo->hashbits == 256)
505 {
506 test<uint256_t>( pInfo->hash, pInfo );
507 }
508 else
509 {
510 printf("Invalid hash bit width %d for hash '%s'",pInfo->hashbits,pInfo->name);
511 }
512 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000513}
514//-----------------------------------------------------------------------------
515
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000516int main ( int argc, char ** argv )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000517{
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000518 const char * hashToTest = "murmur3a";
519
aappleby@google.com7f20a312011-03-21 20:55:06 +0000520 if(argc < 2)
521 {
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000522 printf("(No test hash given on command line, testing Murmur3_x86_32.)\n");
523 }
524 else
525 {
526 hashToTest = argv[1];
aappleby@google.com7f20a312011-03-21 20:55:06 +0000527 }
528
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000529 SetAffinity(2);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000530
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000531 SelfTest();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000532
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000533 int timeBegin = clock();
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000534
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000535 g_testAll = true;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000536
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000537 //g_testSanity = true;
538 //g_testSpeed = true;
aappleby@google.com7f20a312011-03-21 20:55:06 +0000539 //g_testAvalanche = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000540 //g_testBIC = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000541 //g_testCyclic = true;
542 //g_testDiff = true;
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000543 //g_testDiffDist = true;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000544 //g_testSparse = true;
545 //g_testPermutation = true;
546 //g_testZeroes = true;
tanjent@gmail.com31a9e8e2010-11-09 20:29:19 +0000547
tanjent@gmail.com623590d2011-03-28 18:19:31 +0000548 testHash(hashToTest);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000549
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000550 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000551
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000552 int timeEnd = clock();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000553
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000554 printf("\n");
aappleby@google.com7f20a312011-03-21 20:55:06 +0000555 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 +0000556 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 +0000557 printf("-------------------------------------------------------------------------------\n");
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000558 return 0;
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000559}