From ff2e7a35282f46a5364f2d0619e81b3bc6dba2e4 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 29 Jul 2020 13:18:11 -0400 Subject: [PATCH] [enhancement] formatted and added `Hash` directory to cmake (#580) * added hash folder to CMAKE build * split sdbm code from hash.c to independent program * update readme file * docs + vartype fix * split djb2 code from hash.c to independent program * fix function reference * split xor8 code from hash.c to independent program * split adler32 code from hash.c to independent program * remove additional author * split crc32 code from hash.c to independent program * remove redundant files * interpret large numbers as specific types * disable eror clang-diagnostic-implicitly-unsigned-literal * force use constants * updating DIRECTORY.md * clang-tidy fixes for 606e5d4fcebd2645e634de7c03cccb20156ba2fc * added return in function doc to enable doc Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- .clang-tidy | 2 +- CMakeLists.txt | 1 + DIRECTORY.md | 8 +++-- hash/CMakeLists.txt | 20 +++++++++++ hash/README.md | 3 +- hash/hash.c | 82 --------------------------------------------- hash/hash.h | 49 --------------------------- hash/hash_adler32.c | 54 +++++++++++++++++++++++++++++ hash/hash_crc32.c | 62 ++++++++++++++++++++++++++++++++++ hash/hash_djb2.c | 50 +++++++++++++++++++++++++++ hash/hash_sdbm.c | 50 +++++++++++++++++++++++++++ hash/hash_xor8.c | 51 ++++++++++++++++++++++++++++ hash/test_program.c | 20 ----------- 13 files changed, 295 insertions(+), 157 deletions(-) create mode 100644 hash/CMakeLists.txt delete mode 100644 hash/hash.c delete mode 100644 hash/hash.h create mode 100644 hash/hash_adler32.c create mode 100644 hash/hash_crc32.c create mode 100644 hash/hash_djb2.c create mode 100644 hash/hash_sdbm.c create mode 100644 hash/hash_xor8.c delete mode 100644 hash/test_program.c diff --git a/.clang-tidy b/.clang-tidy index e30749e3..1a6c0a47 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- Checks: '-*,google-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,openmp-*,performance-*,portability-*,modernize-*' -WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,' +WarningsAsErrors: '*,-clang-diagnostic-implicitly-unsigned-literal,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 80, AccessModifierOffset: -4 }' diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a70444e..ffd75686 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ endif() ## Add subdirectories containing CMakeLists.txt # to configure and compile files in the respective folders +add_subdirectory(hash) add_subdirectory(misc) add_subdirectory(sorting) add_subdirectory(graphics) diff --git a/DIRECTORY.md b/DIRECTORY.md index a7658523..056d0d62 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -114,9 +114,11 @@ * [Djikstra](https://github.com/TheAlgorithms/C/blob/master/greedy_approach/djikstra.c) ## Hash - * [Hash](https://github.com/TheAlgorithms/C/blob/master/hash/hash.c) - * [Hash](https://github.com/TheAlgorithms/C/blob/master/hash/hash.h) - * [Test Program](https://github.com/TheAlgorithms/C/blob/master/hash/test_program.c) + * [Hash Adler32](https://github.com/TheAlgorithms/C/blob/master/hash/hash_adler32.c) + * [Hash Crc32](https://github.com/TheAlgorithms/C/blob/master/hash/hash_crc32.c) + * [Hash Djb2](https://github.com/TheAlgorithms/C/blob/master/hash/hash_djb2.c) + * [Hash Sdbm](https://github.com/TheAlgorithms/C/blob/master/hash/hash_sdbm.c) + * [Hash Xor8](https://github.com/TheAlgorithms/C/blob/master/hash/hash_xor8.c) ## Leetcode * Src diff --git a/hash/CMakeLists.txt b/hash/CMakeLists.txt new file mode 100644 index 00000000..9c65e096 --- /dev/null +++ b/hash/CMakeLists.txt @@ -0,0 +1,20 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".c" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + if(OpenMP_C_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_C) + endif() + if(MATH_LIBRARY) + target_link_libraries(${testname} ${MATH_LIBRARY}) + endif() + install(TARGETS ${testname} DESTINATION "bin/hash") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/hash/README.md b/hash/README.md index 0d72d6e3..20e201ed 100644 --- a/hash/README.md +++ b/hash/README.md @@ -1,8 +1,7 @@ # Hash algorithms -Overview files **hash.h** and **hash.c** * sdbm * djb2 * xor8 (8 bit) * adler_32 (32 bit) -* crc32 (32 bit) \ No newline at end of file +* crc32 (32 bit) diff --git a/hash/hash.c b/hash/hash.c deleted file mode 100644 index f5eb3fbf..00000000 --- a/hash/hash.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - author: Christian Bender - This is the implementation unit of the hash-functions. - - Overview about hash-functions: - - - sdbm - - djb2 - - xor8 (8 bits) - - adler_32 (32 bits) -*/ - -long long sdbm(char s[]) -{ - long long hash = 0; - int i = 0; - while (s[i] != '\0') - { - hash = s[i] + (hash << 6) + (hash << 16) - hash; - i++; - } - return hash; -} - -long long djb2(char s[]) -{ - long long hash = 5381; /* init value */ - int i = 0; - while (s[i] != '\0') - { - hash = ((hash << 5) + hash) + s[i]; - i++; - } - return hash; -} - -char xor8(char s[]) -{ - int hash = 0; - int i = 0; - while (s[i] != '\0') - { - hash = (hash + s[i]) & 0xff; - i++; - } - return (((hash ^ 0xff) + 1) & 0xff); -} - -int adler_32(char s[]) -{ - int a = 1; - int b = 0; - const int MODADLER = 65521; - - int i = 0; - while (s[i] != '\0') - { - a = (a + s[i]) % MODADLER; - b = (b + a) % MODADLER; - i++; - } - return (b << 16) | a; -} - -/* crc32 Hash-Algorithm*/ -#include - -uint32_t crc32(char *data) -{ - int i = 0; - uint32_t crc = 0xffffffff; - while (data[i] != '\0') - { - uint8_t byte = data[i]; - crc = crc ^ byte; - for (int j = 8; j > 0; --j) - crc = (crc >> 1) ^ (0xEDB88320 & (-(crc & 1))); - - i++; - } - return crc ^ 0xffffffff; -} \ No newline at end of file diff --git a/hash/hash.h b/hash/hash.h deleted file mode 100644 index 3804fca8..00000000 --- a/hash/hash.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - author: Christian Bender - This file contains the public interface - - Overview about hash-functions: - - - sdbm - - djb2 - - xor8 (8 bit) - - adler_32 (32 bits) -*/ - -#ifndef __HASH__H -#define __HASH__H - -/* - sdbm: implements the sdbm hash-algorithm - returns a whole number of type long long. -*/ -long long sdbm(char[]); - -/* - djb2: implements the djb2 hash-algorithm - returns a whole number of type long long. -*/ -long long djb2(char[]); - -/* - xor8: implements the xor8 hash-algorithm - returns a whole number of type char. - length: 8 bit -*/ -char xor8(char[]); - -/* - adler_32: implements the adler-32 hash-algorithm - returns a whole number of type int. - length: 32 bit - assumes: int has a length of 32 bits. -*/ -int adler_32(char[]); - -/* - crc32: implements the crc-32 checksum-algorithm - returns the crc-32 checksum -*/ -int crc32(char[]); - -#endif \ No newline at end of file diff --git a/hash/hash_adler32.c b/hash/hash_adler32.c new file mode 100644 index 00000000..4cd5891e --- /dev/null +++ b/hash/hash_adler32.c @@ -0,0 +1,54 @@ +/** + * @addtogroup hash Hash algorithms + * @{ + * @file hash_adler32.c + * @author [Christian Bender](https://github.com/christianbender) + * @brief 32-bit [Adler hash](https://en.wikipedia.org/wiki/Adler-32) algorithm + */ +#include +#include +#include + +/** + * @brief 32-bit Adler algorithm implementation + * + * @param s NULL terminated ASCII string to hash + * @return 32-bit hash result + */ +uint32_t adler32(const char* s) +{ + uint32_t a = 1; + uint32_t b = 0; + const uint32_t MODADLER = 65521; + + size_t i = 0; + while (s[i] != '\0') + { + a = (a + s[i]) % MODADLER; + b = (b + a) % MODADLER; + i++; + } + return (b << 16) | a; +} + +/** + * @brief Test function for ::adler32 + * \returns None + */ +void test_adler32() +{ + assert(adler32("Hello World") == 403375133); + assert(adler32("Hello World!") == 474547262); + assert(adler32("Hello world") == 413860925); + assert(adler32("Hello world!") == 487130206); + printf("Tests passed\n"); +} + +/** @} */ + +/** Main function */ +int main() +{ + test_adler32(); + return 0; +} diff --git a/hash/hash_crc32.c b/hash/hash_crc32.c new file mode 100644 index 00000000..31d0d427 --- /dev/null +++ b/hash/hash_crc32.c @@ -0,0 +1,62 @@ +/** + * @addtogroup hash Hash algorithms + * @{ + * @file hash_crc32.c + * @author [Christian Bender](https://github.com/christianbender) + * @brief 32-bit [CRC + * hash](https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm) + * algorithm + */ +#include +#include +#include + +/** + * @brief 32-bit CRC algorithm implementation + * + * @param s NULL terminated ASCII string to hash + * @return 32-bit hash result + */ +uint32_t crc32(const char* s) +{ + uint32_t crc = 0xffffffff; + size_t i = 0; + while (s[i] != '\0') + { + uint8_t byte = s[i]; + crc = crc ^ byte; + for (uint8_t j = 8; j > 0; --j) + { + crc = (crc >> 1) ^ (0xEDB88320 & (-(crc & 1))); + } + + i++; + } + return crc ^ 0xffffffff; +} + +/** + * @brief Test function for ::crc32 + * \returns None + */ +void test_crc32() +{ + assert(crc32("Hello World") == 1243066710); + assert(crc32("Hello World!") == 472456355); + assert(crc32("Hello world") == 2346098258); + assert(crc32("Hello world!") == 461707669); + // printf("%" PRIu32 "\n", crc32("Hello World")); + // printf("%" PRIu32 "\n", crc32("Hello World!")); + // printf("%" PRIu32 "\n", crc32("Hello world")); + // printf("%" PRIX32 "\n", crc32("Hello world!")); + printf("Tests passed\n"); +} + +/** @} */ + +/** Main function */ +int main() +{ + test_crc32(); + return 0; +} diff --git a/hash/hash_djb2.c b/hash/hash_djb2.c new file mode 100644 index 00000000..48d0e1f9 --- /dev/null +++ b/hash/hash_djb2.c @@ -0,0 +1,50 @@ +/** + * @addtogroup hash Hash algorithms + * @{ + * @file hash_djb2.c + * @author [Christian Bender](https://github.com/christianbender) + * @brief [DJB2 hash algorithm](http://www.cse.yorku.ca/~oz/hash.html) + */ +#include +#include +#include + +/** + * @brief DJB2 algorithm implementation + * + * @param s NULL terminated string to hash + * @return 64-bit hash result + */ +uint64_t djb2(const char* s) +{ + uint64_t hash = 5381; /* init value */ + size_t i = 0; + while (s[i] != '\0') + { + hash = ((hash << 5) + hash) + s[i]; + i++; + } + return hash; +} + +/** + * Test function for ::djb2 + * \returns none + */ +void test_djb2(void) +{ + assert(djb2("Hello World") == 13827776004929097857); + assert(djb2("Hello World!") == 13594750393630990530); + assert(djb2("Hello world") == 13827776004967047329); + assert(djb2("Hello world!") == 13594750394883323106); + printf("Tests passed\n"); +} + +/** @} */ + +/** Main function */ +int main() +{ + test_djb2(); + return 0; +} diff --git a/hash/hash_sdbm.c b/hash/hash_sdbm.c new file mode 100644 index 00000000..aa3ee0ca --- /dev/null +++ b/hash/hash_sdbm.c @@ -0,0 +1,50 @@ +/** + * @addtogroup hash Hash algorithms + * @{ + * @file hash_sdbm.c + * @author [Christian Bender](https://github.com/christianbender) + * @brief [SDBM hash algorithm](http://www.cse.yorku.ca/~oz/hash.html) + */ +#include +#include +#include + +/** + * @brief SDBM algorithm implementation + * + * @param s NULL terminated string to hash + * @return 64-bit hash result + */ +uint64_t sdbm(const char* s) +{ + uint64_t hash = 0; + size_t i = 0; + while (s[i] != '\0') + { + hash = s[i] + (hash << 6) + (hash << 16) - hash; + i++; + } + return hash; +} + +/** + * @brief Test function for ::sdbm + * \returns None + */ +void test_sdbm() +{ + assert(sdbm("Hello World") == 12881824461405877380); + assert(sdbm("Hello World!") == 7903571203300273309); + assert(sdbm("Hello world") == 15154913742888948900); + assert(sdbm("Hello world!") == 15254999417003201661); + printf("Tests passed\n"); +} + +/** @} */ + +/** Main function */ +int main() +{ + test_sdbm(); + return 0; +} diff --git a/hash/hash_xor8.c b/hash/hash_xor8.c new file mode 100644 index 00000000..f3657829 --- /dev/null +++ b/hash/hash_xor8.c @@ -0,0 +1,51 @@ +/** + * @addtogroup hash Hash algorithms + * @{ + * @file hash_xor8.c + * @author [Christian Bender](https://github.com/christianbender) + * @brief 8-bit [XOR hash](https://en.wikipedia.org/wiki/XOR_cipher) algorithm + * for ASCII characters + */ +#include +#include +#include + +/** + * @brief 8-bit XOR algorithm implementation + * + * @param s NULL terminated ASCII string to hash + * @return 8-bit hash result + */ +uint8_t xor8(const char* s) +{ + uint8_t hash = 0; + size_t i = 0; + while (s[i] != '\0') + { + hash = (hash + s[i]) & 0xff; + i++; + } + return (((hash ^ 0xff) + 1) & 0xff); +} + +/** + * @brief Test function for ::xor8 + * \returns None + */ +void test_xor8() +{ + assert(xor8("Hello World") == 228); + assert(xor8("Hello World!") == 195); + assert(xor8("Hello world") == 196); + assert(xor8("Hello world!") == 163); + printf("Tests passed\n"); +} + +/** @} */ + +/** Main function */ +int main() +{ + test_xor8(); + return 0; +} diff --git a/hash/test_program.c b/hash/test_program.c deleted file mode 100644 index ab93bab9..00000000 --- a/hash/test_program.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - author: Christian Bender - This file contains a simple test program for each hash-function. -*/ - -#include -#include "hash.h" - -int main(void) -{ - char s[] = "hello"; - - /* actual tests */ - printf("sdbm: %s --> %llX\n", s, sdbm(s)); - printf("djb2: %s --> %llX\n", s, djb2(s)); - printf("xor8: %s --> %X\n", s, xor8(s)); /* 8 bit */ - printf("adler_32: %s --> %X\n", s, adler_32(s)); /* 32 bit */ - - return 0; -}