1 /// Implementation of SuperFastHash digester.
2 module tern.digest.superfasthash;
3 
4 import tern.serialization;
5 import tern.digest;
6 
7 /**
8  * Implementation of SuperFastHash digester.
9  *
10  * SuperFastHash is a non-cryptographic hash function designed for fast hash calculations
11  * on small data blocks. It is commonly used in applications where speed is critical.
12  *
13  * Example:
14  * ```d
15  * import tern.digest.superfasthash;
16  * 
17  * ubyte[] data = [1, 2, 3, 4, 5];
18  * auto hashValue = SuperFastHash.hash(data);
19  * ```
20  */
21 public static @digester class SuperFastHash
22 {
23 public:
24 static:
25 pure:
26     /**
27      * Computes the SuperFastHash digest of the given data.
28      *
29      * Params:
30      *  data = The input byte array for which the SuperFastHash is to be computed.
31      *
32      * Returns:
33      *  A byte array representing the computed SuperFastHash digest.
34      */
35     ubyte[] hash(ubyte[] data)
36     {
37         size_t index = 0;
38         size_t digest = data.length;
39 
40         foreach_reverse (n; 0..(data.length >> 2)) 
41         {
42             digest += (data[index++] | (data[index++] << 8));
43             digest ^= (digest << 16) ^ ((data[index++] | (data[index++] << 8)) << 11);
44             digest += digest >> 11;
45         }
46 
47         switch (data.length & 3) {
48             case 3:
49                 digest += (data[index++] | (data[index++] << 8));
50                 digest ^= (digest << 16);
51                 digest ^= (data[index++] << 18);
52                 digest += digest >> 11;
53                 break;
54             case 2:
55                 digest += (data[index++] | (data[index++] << 8));
56                 digest ^= (digest << 11);
57                 digest += digest >> 17;
58                 break;
59             default:
60                 digest += data[index++];
61                 digest ^= (digest << 10);
62                 digest += digest >> 1;
63                 break;
64         }
65 
66         digest ^= (digest << 3);
67         digest += digest >> 5;
68         digest ^= (digest << 4);
69         digest += digest >> 17;
70         digest ^= (digest << 25);
71         digest += digest >> 6;
72 
73         return digest.serialize!true();
74     }
75 }