From: Jesper Dangaard Brouer Date: Thu, 25 Jan 2018 19:24:33 +0000 (+0100) Subject: ebpf: add Paul Hsieh's (LGPL 2.1) hash function SuperFastHash X-Git-Tag: suricata-4.1.0-beta1~178 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=460a0a6977614a521ebb17cc8e531c6528ff8c69;p=thirdparty%2Fsuricata.git ebpf: add Paul Hsieh's (LGPL 2.1) hash function SuperFastHash Adjusted function call API to take an initval. This allow the API user to set the initial value, as a seed. This could also be used for inputting the previous hash. Signed-off-by: Jesper Dangaard Brouer --- diff --git a/ebpf/hash_func01.h b/ebpf/hash_func01.h new file mode 100644 index 0000000000..060346f67a --- /dev/null +++ b/ebpf/hash_func01.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1 + * + * Based on Paul Hsieh's (LGPG 2.1) hash function + * From: http://www.azillionmonkeys.com/qed/hash.html + */ + +#define get16bits(d) (*((const uint16_t *) (d))) + +static __always_inline +uint32_t SuperFastHash (const char *data, int len, uint32_t initval) { + uint32_t hash = initval; + uint32_t tmp; + int rem; + + if (len <= 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + /* Main loop */ +#pragma clang loop unroll(full) + for (;len > 0; len--) { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= ((signed char)data[sizeof (uint16_t)]) << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += (signed char)*data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +}