aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
2 files changed, 31 insertions, 0 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index 14658962b..39fd6bfb3 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -1087,6 +1087,7 @@ extern "C" {
u_int8_t num_clusters, u_int16_t *cluster_ids,
struct ndpi_bin *centroids);
+ u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long);
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index b96f52531..634b02d59 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1765,3 +1765,33 @@ ndpi_http_method ndpi_http_str2method(const char* method, ssize_t method_len) {
return(NDPI_HTTP_METHOD_UNKNOWN);
}
+
+/* ******************************************************************** */
+
+#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r))))
+
+/*
+ 'in_16_bytes_long` points to some 16 byte memory data to be hashed;
+ two independent 64-bit linear congruential generators are applied
+ results are mixed, scrambled and cast to 32-bit
+*/
+u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long) {
+ u_int64_t a = *(u_int64_t*)(in_16_bytes_long + 0);
+ u_int64_t c = *(u_int64_t*)(in_16_bytes_long + 8);
+
+ // multipliers are taken from sprng.org, addends are prime
+ a = a * 0x2c6fe96ee78b6955 + 0x9af64480a3486659;
+ c = c * 0x369dea0f31a53f85 + 0xd0c6225445b76b5b;
+
+ // mix results
+ a += c;
+
+ // final scramble
+ a ^= ROR64(a, 13) ^ ROR64(a, 7);
+
+ // down-casting, also taking advantage of upper half
+ a ^= a >> 32;
+
+ return((u_int32_t)a);
+}
+