]> git.tdb.fi Git - libs/core.git/commitdiff
Hash functions
authorMikko Rasa <tdb@tdb.fi>
Sun, 4 Sep 2011 19:17:38 +0000 (22:17 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 4 Sep 2011 19:18:10 +0000 (22:18 +0300)
source/core/hash.cpp [new file with mode: 0644]
source/core/hash.h [new file with mode: 0644]

diff --git a/source/core/hash.cpp b/source/core/hash.cpp
new file mode 100644 (file)
index 0000000..26e6059
--- /dev/null
@@ -0,0 +1,49 @@
+#include <stdexcept>
+#include "hash.h"
+
+using namespace std;
+
+namespace Msp {
+
+/*
+http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
+http://www.isthe.com/chongo/tech/comp/fnv/index.html
+*/
+
+unsigned hash32(const void *data, unsigned size, unsigned bits)
+{
+       if(bits==0 || bits>32)
+               throw invalid_argument("hash32");
+
+       static const unsigned prime = 16777619;
+       static const unsigned offset = 2166136261U;
+
+       unsigned result = offset;
+       for(unsigned i=0; i<size; ++i)
+               result = (result^*(reinterpret_cast<const unsigned char *>(data)+i))*prime;
+
+       if(bits<32)
+               result = (result>>bits ^ result) & ((1<<bits)-1);
+
+       return result;
+}
+
+HashValue64 hash64(const void *data, unsigned size, unsigned bits)
+{
+       if(bits==0 || bits>64)
+               throw invalid_argument("hash64");
+
+       static const HashValue64 prime = 1099511628211ULL;
+       static const HashValue64 offset = 14695981039346656037ULL;
+
+       HashValue64 result = offset;
+       for(unsigned i=0; i<size; ++i)
+               result = (result^*(reinterpret_cast<const unsigned char *>(data)+i))*prime;
+
+       if(bits<64)
+               result = (result>>bits ^ result) & ((1ULL<<bits)-1);
+
+       return result;
+}
+
+} // namespace Msp
diff --git a/source/core/hash.h b/source/core/hash.h
new file mode 100644 (file)
index 0000000..1eebcce
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef MSP_CORE_HASH_H_
+#define MSP_CORE_HASH_H_
+
+#include <string>
+
+namespace Msp {
+
+#ifdef WIN32
+typedef __uint64 HashValue64;
+#else
+typedef unsigned long long HashValue64;
+#endif
+
+/**
+Computes a 32-bit Fowler-Noll-Vo (FNV-1a) hash.  The number of bits can be
+limited to less than 32, in which case XOR-folding is used to reduce the hash
+size.
+*/
+unsigned hash32(const void *, unsigned, unsigned = 32);
+
+/**
+Convenience function to compute a 32-bit hash of a string.
+*/
+inline unsigned hash32(const std::string &s, unsigned b = 32)
+{ return hash32(s.data(), s.size(), b); }
+
+/**
+Computes a 64-bit Fowler-Noll-Vo (FNV-1a) hash.  Note that even if bits is
+limited to 32 or less, this does not produce the same result as hash32.
+*/
+HashValue64 hash64(const void *, unsigned, unsigned = 64);
+
+/**
+Convenience function to compute a 64-bit hash of a string.
+*/
+inline HashValue64 hash64(const std::string &s, unsigned b = 64)
+{ return hash64(s.data(), s.size(), b); }
+
+} // namespace Msp
+
+#endif