1 /// Implementation of MurmurHash digester. 2 module tern.digest.murmurhash; 3 4 import tern.memory; 5 import tern.serialization; 6 import tern.digest; 7 import core.bitop; 8 9 /** 10 * Implementation of MurmurHash digester. 11 * 12 * MurmurHash is a non-cryptographic hash function suitable for general hash-based 13 * lookup. It provides fast and relatively good distribution of hash values. 14 * 15 * Example: 16 * ```d 17 * ubyte[] data = [1, 2, 3, 4, 5]; 18 * auto hashValue = MurmurHash.hash(data); 19 * ``` 20 */ 21 public static @digester class MurmurHash 22 { 23 private: 24 static: 25 pure: 26 enum C1 = 0xcc9e2d51; 27 enum C2 = 0x1b873593; 28 enum R1 = 15; 29 enum R2 = 13; 30 enum M = 5; 31 enum N = 0xe6546b64; 32 33 public: 34 /** 35 * Computes the MurmurHash digest of the given data. 36 * 37 * Params: 38 * data = The input byte array for which the hash is to be computed. 39 * seed = An optional seed value used to initialize the hash function. Defaults to 0. 40 * 41 * Returns: 42 * An array of bytes representing the computed MurmurHash digest. 43 */ 44 ubyte[] hash(ubyte[] data, uint seed = 0) 45 { 46 sachp(data, 4); 47 48 uint hash = seed; 49 foreach (k; cast(uint[])data) 50 { 51 k *= C1; 52 k = rol(k, R1); 53 k *= C2; 54 55 hash ^= k; 56 hash = rol(hash, R2); 57 hash = hash * M + N; 58 } 59 60 hash ^= data.length * 4; 61 hash ^= hash >> 16; 62 hash *= 0x85ebca6b; 63 hash ^= hash >> 13; 64 hash *= 0xC2b2ae35; 65 hash ^= hash >> 16; 66 67 return hash.serialize!true(); 68 } 69 }