22 #include <boost/functional/hash.hpp> 23 #include <boost/lexical_cast.hpp> 28 using boost::lexical_cast;
61 typedef boost::hash<string> BoostStringHasher;
62 typedef std::map<size_t, string> StringsTable;
78 BoostStringHasher hashFunction;
79 StringsTable hashValues;
80 string prefix =
"Entry.";
82 for (uint i=0; i<100000; ++i)
84 string candidate = prefix + lexical_cast<
string> (i);
85 size_t hashVal = hashFunction(candidate);
87 if (contains (hashValues, hashVal))
90 string other = hashValues[hashVal];
91 cout <<
"Duplicate at "<< i << endl;
92 cout <<
"existing--->" << other << endl;
93 cout <<
"new-------->" << candidate << endl;
95 size_t exHash = hashFunction(other);
96 size_t newHash = hashFunction(candidate);
97 cout <<
"hash-ex---->" << exHash << endl;
98 cout <<
"hash_new--->" << newHash << endl;
100 hashValues[hashVal] = candidate;
103 cout <<
"boost::hash for strings produced "<<collisions<<
" collisions. This is a known problem."<<endl;
105 cout <<
"SURPRISE. No collisions with the boost::hash function." <<endl;
126 StringsTable hashValues;
127 string prefix =
"Entry.";
128 const size_t seed =
rani();
133 for (uint i=0; i<20000; ++i)
135 string candidate = prefix + lexical_cast<
string> (i);
136 size_t l = candidate.length();
137 size_t hashVal = seed;
139 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-1]);
140 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-2]);
141 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-3]);
142 boost::hash_combine(hashVal, KNUTH_MAGIC * candidate[l-4]);
143 boost::hash_combine(hashVal, candidate);
145 if (contains (hashValues, hashVal))
148 string other = hashValues[hashVal];
149 cout <<
"Hash collision between " << i <<
" and " << other <<endl;
151 hashValues[hashVal] = candidate;
153 CHECK (!collisions,
"the Knuth trick failed to spread our hash values evenly enough, what a shame...");
void demonstrate_boost_hash_weakness()
const size_t KNUTH_MAGIC
lousy old tinkerer's trick: hash values with poor distribution can be improved by spreading the input...
int rani(uint bound=_iBOUND())
Implementation namespace for support and library code.
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void verify_Knuth_workaround()
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container