libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2021-09-04 02:07:48
Commit12c01d4fee3fe8de2517207d3d022e79e4d38e54
Parent406a4fab376d0a53435fadcf564b6ccd1ff37b7d

fnv: Add FNV hashing algorithms

Diffstat

M CMakeLists.txt | 2 ++
M README.md | 1 +
A src/fnv.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A src/fnv.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
A src/test/test_fnv.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

5 files changed, 174 insertions, 0 deletions

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 096c3ca..7791bbc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,6 +19,7 @@ ADD_EXECUTABLE(test_base64 ${PROJECT_SOURCE_DIR}/src/test/test_base64.c)
 ADD_EXECUTABLE(test_crypt  ${PROJECT_SOURCE_DIR}/src/test/test_crypt.c)
 ADD_EXECUTABLE(test_endian ${PROJECT_SOURCE_DIR}/src/test/test_endian.c)
 ADD_EXECUTABLE(test_error  ${PROJECT_SOURCE_DIR}/src/test/test_error.c)
+ADD_EXECUTABLE(test_fnv    ${PROJECT_SOURCE_DIR}/src/test/test_fnv.c)
 ADD_EXECUTABLE(test_optget ${PROJECT_SOURCE_DIR}/src/test/test_optget.c)
 ADD_EXECUTABLE(test_rc2    ${PROJECT_SOURCE_DIR}/src/test/test_rc2.c)
 ADD_EXECUTABLE(test_strtou ${PROJECT_SOURCE_DIR}/src/test/test_strtou.c)
@@ -29,6 +30,7 @@ ADD_TEST(NAME test_base64 COMMAND test_base64)
 ADD_TEST(NAME test_crypt  COMMAND test_crypt)
 ADD_TEST(NAME test_endian COMMAND test_endian)
 ADD_TEST(NAME test_error  COMMAND test_error)
+ADD_TEST(NAME test_fnv    COMMAND test_fnv)
 ADD_TEST(NAME test_optget COMMAND test_optget)
 ADD_TEST(NAME test_rc2    COMMAND test_rc2)
 ADD_TEST(NAME test_strtou COMMAND test_strtou)
diff --git a/README.md b/README.md
index d78971c..97b6946 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@
 | crypt            | Cryptography functions                   |          |
 | endian           | Endianness related functions             |          |
 | error            | Error reporting functions                |          |
+| fnv              | FNV hashing algorithms                   |          |
 | mode             | Parse numeric or symbolic POSIX modes    |          |
 | optget           | Parse command line options               |          |
 | rc2              | RC2 encryption algorithm                 | RFC 2268 |
diff --git a/src/fnv.c b/src/fnv.c
new file mode 100644
index 0000000..d83c1d6
--- /dev/null
+++ b/src/fnv.c
@@ -0,0 +1,63 @@
+// fnv.c
+// FNV hash source file for libcll
+// Copyright (C) 2021, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Permissive Licence, version 1.0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+#include "fnv.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+static const uint32_t FNV_PRIME_32 = 0x01000193;
+static const uint32_t FNV_BASIS_32 = 0x811C9DC5;
+static const uint64_t FNV_PRIME_64 = 0x00000100000001B3;
+static const uint64_t FNV_BASIS_64 = 0xCBF29CE484222325;
+
+/* Compute the FNV1a-32 hash of some data. */
+uint32_t fnv1a32(uint8_t *dat, size_t len) {
+	register uint32_t fnv = FNV_BASIS_32;
+	for (; len; --len, ++dat) { fnv ^= *dat; fnv *= FNV_PRIME_32; } return fnv;
+}
+
+/* Compute the FNV1a-64 hash of some data. */
+uint64_t fnv1a64(uint8_t *dat, size_t len) {
+	register uint64_t fnv = FNV_BASIS_64;
+	for (; len; --len, ++dat) { fnv ^= *dat; fnv *= FNV_PRIME_64; } return fnv;
+}
+
+void fnv1a32_init(uint32_t *ctx) { *ctx = FNV_BASIS_32; }
+void fnv1a32_hash(uint32_t *ctx, uint8_t *dat, size_t len) {
+	for (; len; --len, ++dat) { *ctx ^= *dat; *ctx *= FNV_PRIME_32; }
+}
+
+void fnv1a64_init(uint64_t *ctx) { *ctx = FNV_BASIS_64; }
+void fnv1a64_hash(uint64_t *ctx, uint8_t *dat, size_t len) {
+	for (; len; --len, ++dat) { *ctx ^= *dat; *ctx *= FNV_PRIME_64; }
+}
diff --git a/src/fnv.h b/src/fnv.h
new file mode 100644
index 0000000..ae56e60
--- /dev/null
+++ b/src/fnv.h
@@ -0,0 +1,48 @@
+// fnv.h
+// FNV hash header file for libcll
+// Copyright (C) 2021, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Permissive Licence, version 1.0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+#ifndef OMKOV_LIBCLL_FNV_H_O4TYU6Q1
+#define OMKOV_LIBCLL_FNV_H_O4TYU6Q1
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern uint32_t fnv1a32(uint8_t *dat, size_t len);
+extern uint64_t fnv1a64(uint8_t *dat, size_t len);
+
+extern void fnv1a32_init(uint32_t *ctx);
+extern void fnv1a32_hash(uint32_t *ctx, uint8_t *dat, size_t len);
+
+extern void fnv1a64_init(uint64_t *ctx);
+extern void fnv1a64_hash(uint64_t *ctx, uint8_t *dat, size_t len);
+
+#endif // OMKOV_LIBCLL_FNV_H_O4TYU6Q1
diff --git a/src/test/test_fnv.c b/src/test/test_fnv.c
new file mode 100644
index 0000000..d68dcc1
--- /dev/null
+++ b/src/test/test_fnv.c
@@ -0,0 +1,60 @@
+// test_fnv.c
+// FNV unit test for libcll
+// Copyright (C) 2021, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Public Domain Licence, version 1.0
+
+Permission is hereby granted to deal with this software and its associated
+documentation files without restriction.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+#include "../fnv.h"
+#include "unit.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(void) {
+	{
+		uint8_t i[9] = "123456789"; uint32_t fnv32;
+		
+		fnv32 = fnv1a32(i, 9);
+		ASSERT("T000 HASH STRING fnv1a32()", fnv32 == 0xBB86B11C);
+	}
+	
+	{
+		uint8_t i[9] = "123456789"; uint32_t fnv32;
+		
+		fnv1a32_init(&fnv32);
+		fnv1a32_hash(&fnv32, i, 9);
+		ASSERT("T001 HASH STRING fnv1a32_hash()", fnv32 == 0xBB86B11C);
+	}
+	
+	{
+		uint8_t i[9] = "123456789"; uint64_t fnv64;
+		
+		fnv64 = fnv1a64(i, 9);
+		ASSERT("T002 HASH STRING fnv1a64()", fnv64 == 0x06D5573923C6CDFC);
+	}
+	
+	{
+		uint8_t i[9] = "123456789"; uint64_t fnv64;
+		
+		fnv1a64_init(&fnv64);
+		fnv1a64_hash(&fnv64, i, 9);
+		ASSERT("T003 HASH STRING fnv1a64_hash()", fnv64 == 0x06D5573923C6CDFC);
+	}
+	
+	printf("%d of %d tests passed\n", testspassed, testsrun);
+	return testsfailed;
+}