diff --git a/modules/ripple_basics/types/ripple_HashMaps.h b/modules/ripple_basics/types/ripple_HashMaps.h index 1fad631367..dfae29040c 100644 --- a/modules/ripple_basics/types/ripple_HashMaps.h +++ b/modules/ripple_basics/types/ripple_HashMaps.h @@ -15,6 +15,28 @@ class HashMaps // : beast::Uncopayble { public: + /** Golden ratio constant used in hashing functions. + + The magic number is supposed to be 32 random bits, where each is + equally likely to be 0 or 1, and with no simple correlation between + the bits. A common way to find a string of such bits is to use the + binary expansion of an irrational number; in this case, that number + is the reciprocal of the golden ratio: + + @code + + phi = (1 + sqrt(5)) / 2 + 2^32 / phi = 0x9e3779b9 + + @endcode + + References: + + http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine + http://burtleburtle.net/bob/hash/doobs.html + */ + static std::size_t const goldenRatio = 0x9e3779b9; + /** Retrieve the singleton. @return The global instance of the singleton. diff --git a/modules/ripple_data/crypto/ripple_Base58Data.cpp b/modules/ripple_data/crypto/ripple_Base58Data.cpp index 6623a79d34..224f91411c 100644 --- a/modules/ripple_data/crypto/ripple_Base58Data.cpp +++ b/modules/ripple_data/crypto/ripple_Base58Data.cpp @@ -109,16 +109,8 @@ bool CBase58Data::operator> (const CBase58Data& b58) const { return CompareTo(b5 std::size_t hash_value(const CBase58Data& b58) { - // VFALCO: TODO, figure out what this is for and whether or - // not it affects the protocol specification. - // - // NOTE, this constant is used elsewhere as well. - // should it be DRY? - // - const std::size_t mysteriousConstant = 0x9e3779b9; - std::size_t seed = HashMaps::getInstance ().getNonce () - + (b58.nVersion * mysteriousConstant); + + (b58.nVersion * HashMaps::goldenRatio); boost::hash_combine (seed, b58.vchData); diff --git a/src/cpp/ripple/SHAMap.cpp b/src/cpp/ripple/SHAMap.cpp index c232eec723..a0b02a2302 100644 --- a/src/cpp/ripple/SHAMap.cpp +++ b/src/cpp/ripple/SHAMap.cpp @@ -26,21 +26,13 @@ void SHAMapNode::setMHash() const { using namespace std; - // VFALCO: TODO, figure out what this is for and whether or - // not it affects the protocol specification. - // - // NOTE, this constant is used elsewhere as well. - // should it be DRY? - // - const std::size_t mysteriousConstant = 0x9e3779b9; - std::size_t h = HashMaps::getInstance ().getNonce () - + (mDepth * mysteriousConstant); + + (mDepth * HashMaps::goldenRatio); const unsigned int *ptr = reinterpret_cast (mNodeID.begin()); for (int i = (mDepth + 7) / 8; i != 0; --i) - h = (h * mysteriousConstant) ^ *ptr++; + h = (h * HashMaps::goldenRatio) ^ *ptr++; mHash = h; }