summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/hash.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2013-10-06 17:13:27 +0200
committerAdam Borowski <kilobyte@angband.pl>2013-10-06 17:13:27 +0200
commitc47ee9af642d5ad698871c7ce31e5ffae6a51d98 (patch)
tree7dc371cd8bf5e7850e0a1a0f077ed1a8cb46956a /crawl-ref/source/hash.cc
parent4ee4bd8e3265b59996e467dcd555a7bccad1f9ee (diff)
downloadcrawl-ref-c47ee9af642d5ad698871c7ce31e5ffae6a51d98.tar.gz
crawl-ref-c47ee9af642d5ad698871c7ce31e5ffae6a51d98.zip
Rename rng.cc to hash.cc
As that's all that's left.
Diffstat (limited to 'crawl-ref/source/hash.cc')
-rw-r--r--crawl-ref/source/hash.cc61
1 files changed, 61 insertions, 0 deletions
diff --git a/crawl-ref/source/hash.cc b/crawl-ref/source/hash.cc
new file mode 100644
index 0000000000..5f38a3416f
--- /dev/null
+++ b/crawl-ref/source/hash.cc
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * @brief Hashes.
+**/
+
+#include "AppHdr.h"
+#include "hash.h"
+
+//-----------------------------------------------------------------------------
+// MurmurHash2, by Austin Appleby
+uint32_t hash32(const void *data, int len)
+{
+ // 'm' and 'r' are mixing constants generated offline.
+ // They're not really 'magic', they just happen to work well.
+ const uint32_t m = 0x5bd1e995;
+
+ // Initialize the hash to a 'random' value
+ uint32_t h = len;
+
+ const uint8_t *d = (const uint8_t*)data;
+ // Mix 4 bytes at a time into the hash
+ while (len >= 4)
+ {
+ uint32_t k = htole32(*(uint32_t *)d);
+
+ k *= m;
+ k ^= k >> 24;
+ k *= m;
+
+ h *= m;
+ h ^= k;
+
+ d += 4;
+ len -= 4;
+ }
+
+ // Handle the last few bytes of the input array
+ switch (len)
+ {
+ case 3: h ^= (uint32_t)d[2] << 16;
+ case 2: h ^= (uint32_t)d[1] << 8;
+ case 1: h ^= (uint32_t)d[0];
+ h *= m;
+ };
+
+ // Do a few final mixes of the hash to ensure the last few
+ // bytes are well-incorporated.
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+unsigned int hash_rand(int x, uint32_t seed, uint32_t id)
+{
+ if (x < 2)
+ return 0;
+ uint32_t data[2] = {seed, id};
+ return hash32(data, 2 * sizeof(int32_t)) % x;
+}