/src/ndpi/src/lib/ndpi_hash.c
Line | Count | Source |
1 | | /* |
2 | | * ndpi_bitmap.c |
3 | | * |
4 | | * Copyright (C) 2011-25 - ntop.org and contributors |
5 | | * |
6 | | * nDPI is free software: you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation, either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * nDPI is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with nDPI. If not, see <http://www.gnu.org/licenses/>. |
18 | | * |
19 | | */ |
20 | | |
21 | | |
22 | | #include "ndpi_config.h" |
23 | | #include "ndpi_api.h" |
24 | | |
25 | | #include "third_party/include/MurmurHash3.h" |
26 | | |
27 | | /* ******************************************************************** */ |
28 | | |
29 | | /* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */ |
30 | 202 | u_int32_t ndpi_murmur_hash(const char *str, u_int str_len) { |
31 | 202 | return(MurmurHash((void*)str, str_len, 0x87654321)); |
32 | 202 | } |
33 | | |
34 | | /* ******************************************************************** */ |
35 | | |
36 | | /* Based on djb2 hash - http://www.cse.yorku.ca/~oz/hash.html */ |
37 | 14.1M | u_int32_t ndpi_quick_hash(const unsigned char *str, u_int str_len) { |
38 | 14.1M | u_int32_t hash = 5381, i; |
39 | | |
40 | 195M | for(i=0; i<str_len; i++) |
41 | 181M | hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */ |
42 | | |
43 | 14.1M | return(hash); |
44 | 14.1M | } |
45 | | |
46 | | /* ******************************************************************** */ |
47 | | |
48 | 481k | u_int64_t ndpi_quick_hash64(const char *str, u_int str_len) { |
49 | 481k | u_int64_t h = 177; |
50 | 481k | u_int i; |
51 | | |
52 | 14.5M | for(i=0; i<str_len; i++) |
53 | 14.0M | h = (h * 31) + str[i]; |
54 | | |
55 | 481k | h ^= str_len; |
56 | | |
57 | 481k | return h; |
58 | 481k | } |
59 | | |
60 | | /* ******************************************************************** */ |
61 | | |
62 | | /* |
63 | | https://en.wikipedia.org/wiki/Jenkins_hash_function |
64 | | |
65 | | See also http://burtleburtle.net/bob/hash/spooky.html |
66 | | */ |
67 | 202 | u_int32_t ndpi_hash_string(const char *str) { |
68 | 202 | u_int32_t hash, i; |
69 | | |
70 | 6.36M | for(hash = i = 0; str[i] != '\0'; ++i) { |
71 | 6.36M | hash += str[i]; |
72 | 6.36M | hash += (hash << 10); |
73 | 6.36M | hash ^= (hash >> 6); |
74 | 6.36M | } |
75 | | |
76 | 202 | hash += (hash << 3); |
77 | 202 | hash ^= (hash >> 11); |
78 | 202 | hash += (hash << 15); |
79 | | |
80 | 202 | return(hash); |
81 | 202 | } |
82 | | |
83 | | /* ******************************************************************** */ |
84 | | |
85 | 202 | u_int32_t ndpi_rev_hash_string(const char *str) { |
86 | 202 | u_int32_t hash, i; |
87 | 202 | int len = strlen(str); |
88 | | |
89 | 202 | if(len == 0) return(0); |
90 | 182 | len--; |
91 | | |
92 | 6.36M | for(hash = i = 0; len >= 0; len--) { |
93 | 6.36M | hash += str[len]; |
94 | 6.36M | hash += (hash << 10); |
95 | 6.36M | hash ^= (hash >> 6); |
96 | 6.36M | } |
97 | | |
98 | 182 | hash += (hash << 3); |
99 | 182 | hash ^= (hash >> 11); |
100 | 182 | hash += (hash << 15); |
101 | | |
102 | 182 | return(hash); |
103 | 202 | } |
104 | | |
105 | | /* ******************************************************************** */ |
106 | | |
107 | | /* Same as above but with strings with lenght */ |
108 | 202 | u_int32_t ndpi_hash_string_len(const char *str, u_int len) { |
109 | 202 | u_int32_t hash, i; |
110 | | |
111 | 6.36M | for(hash = i = 0; i< len; ++i) { |
112 | 6.36M | hash += str[i]; |
113 | 6.36M | hash += (hash << 10); |
114 | 6.36M | hash ^= (hash >> 6); |
115 | 6.36M | } |
116 | | |
117 | 202 | hash += (hash << 3); |
118 | 202 | hash ^= (hash >> 11); |
119 | 202 | hash += (hash << 15); |
120 | | |
121 | 202 | return(hash); |
122 | 202 | } |
123 | | |
124 | | /* ******************************************************************** */ |
125 | | |
126 | 358 | #define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) |
127 | | |
128 | | /* |
129 | | 'in_16_bytes_long` points to some 16 byte memory data to be hashed; |
130 | | two independent 64-bit linear congruential generators are applied |
131 | | results are mixed, scrambled and cast to 32-bit |
132 | | */ |
133 | 179 | u_int32_t ndpi_quick_16_byte_hash(const u_int8_t *in_16_bytes_long) { |
134 | 179 | u_int64_t a = *(u_int64_t*)(in_16_bytes_long + 0); |
135 | 179 | u_int64_t c = *(u_int64_t*)(in_16_bytes_long + 8); |
136 | | |
137 | | // multipliers are taken from sprng.org, addends are prime |
138 | 179 | a = a * 0x2c6fe96ee78b6955 + 0x9af64480a3486659; |
139 | 179 | c = c * 0x369dea0f31a53f85 + 0xd0c6225445b76b5b; |
140 | | |
141 | | // mix results |
142 | 179 | a += c; |
143 | | |
144 | | // final scramble |
145 | 179 | a ^= ROR64(a, 13) ^ ROR64(a, 7); |
146 | | |
147 | | // down-casting, also taking advantage of upper half |
148 | 179 | a ^= a >> 32; |
149 | | |
150 | 179 | return((u_int32_t)a); |
151 | 179 | } |