Author | Jamozed <[email protected]> |
Date | 2021-09-04 02:07:48 |
Commit | 12c01d4fee3fe8de2517207d3d022e79e4d38e54 |
Parent | 406a4fab376d0a53435fadcf564b6ccd1ff37b7d |
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; +}