1 module nxt.knuthhash64; 2 3 @safe pure nothrow @nogc: 4 5 /** Knuth hash. 6 * 7 * See_Also: https://stackoverflow.com/a/9545731/683710 8 */ 9 struct KnuthHash64() // dummy templatized to prevent instantiation 10 { 11 @safe pure nothrow @nogc: 12 13 pragma(msg, "WARNING: this hash really sucks collisionwise and should not be used in production!"); 14 15 /** (Re)initialize. 16 */ 17 void start() 18 { 19 _result = _seedValue; 20 } 21 22 /** Use this to feed the hash with `data`. 23 * 24 * Also implements the $(XREF range, OutputRange) interface for $(D ubyte) 25 * and $(D const(ubyte)[]). 26 */ 27 void put(scope const(ubyte)[] data...) @trusted 28 { 29 foreach (elt; data) 30 { 31 _result += elt; 32 _result *= _mulFactor; 33 } 34 } 35 36 /** Returns: the finished hash. 37 * 38 * This also calls $(LREF start) to reset the internal _state. 39 */ 40 ubyte[8] finish() @trusted 41 { 42 version(D_Coverage) {} else pragma(inline, true); 43 typeof(return) bytes = (cast(ubyte*)&_result)[0 .. typeof(return).sizeof]; 44 start(); 45 return bytes; 46 } 47 48 ulong get() 49 { 50 return _result; 51 } 52 53 private: 54 private enum _seedValue = 3074457345618258791UL; 55 private enum _mulFactor = 3074457345618258799UL; 56 ulong _result = _seedValue; 57 } 58 59 /** Compute knuthHash-64 of input `data`, with optional seed `seed`. 60 */ 61 ulong knuthhash64Of()(scope const(ubyte)[] data, ulong seed = 0) 62 { 63 auto hash = KnuthHash64!()(seed); 64 hash.start(); 65 hash.put(data); 66 return hash.get(); 67 } 68 69 /** Compute knuthHash-64 of input string `data`, with optional seed `seed`. 70 */ 71 ulong knuthhash64Of()(in char[] data, ulong seed = 0) 72 @trusted 73 { 74 return knuthhash64Of(cast(ubyte[])data, seed); 75 } 76 77 /// test simple `knuthhash64Of` 78 // unittest 79 // { 80 // assert(knuthhash64Of("") == KnuthHash64!()._seedValue); 81 // assert(knuthhash64Of("a") != KnuthHash64!()._seedValue); 82 // assert(knuthhash64Of("a") != knuthhash64Of("b")); 83 // } 84 85 // version(unittest) 86 // { 87 // import std.digest : isDigest; 88 // static assert(isDigest!(KnuthHash64!())); 89 // }