summaryrefslogtreecommitdiff
path: root/deps/theft/theft_hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/theft/theft_hash.c')
-rw-r--r--deps/theft/theft_hash.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/deps/theft/theft_hash.c b/deps/theft/theft_hash.c
new file mode 100644
index 0000000..2ffa202
--- /dev/null
+++ b/deps/theft/theft_hash.c
@@ -0,0 +1,37 @@
+#include "theft.h"
+
+/* Fowler/Noll/Vo hash, 64-bit FNV-1a.
+ * This hashing algorithm is in the public domain.
+ * For more details, see: http://www.isthe.com/chongo/tech/comp/fnv/. */
+static const uint64_t fnv64_prime = 1099511628211L;
+static const uint64_t fnv64_offset_basis = 14695981039346656037UL;
+
+/* Init a hasher for incremental hashing. */
+void theft_hash_init(struct theft_hasher *h) {
+ h->accum = fnv64_offset_basis;
+}
+
+/* Sink more data into an incremental hash. */
+void theft_hash_sink(struct theft_hasher *h, uint8_t *data, size_t bytes) {
+ if (h == NULL || data == NULL) { return; }
+ uint64_t a = h->accum;
+ for (size_t i = 0; i < bytes; i++) {
+ a = (a ^ data[i]) * fnv64_prime;
+ }
+ h->accum = a;
+}
+
+/* Finish hashing and get the result. */
+theft_hash theft_hash_done(struct theft_hasher *h) {
+ theft_hash res = h->accum;
+ theft_hash_init(h); /* reset */
+ return res;
+}
+
+/* Hash a buffer in one pass. (Wraps the above functions.) */
+theft_hash theft_hash_onepass(uint8_t *data, size_t bytes) {
+ struct theft_hasher h;
+ theft_hash_init(&h);
+ theft_hash_sink(&h, data, bytes);
+ return theft_hash_done(&h);
+}