aboutsummaryrefslogtreecommitdiff
path: root/src/algo
diff options
context:
space:
mode:
authorbenj <benj@rse8.com>2017-06-16 01:20:02 -0700
committerbenj <benj@rse8.com>2017-06-16 01:20:02 -0700
commit14adc6a1d769e22958496d570b7f25b68cc86969 (patch)
tree6754de138c6d59bbfce8d5a3b732891d5a5e220b /src/algo
parentdee453b6473354786871a9b0b123d676ef1eb5cc (diff)
downloadworkbench-master.tar
workbench-master.tar.gz
workbench-master.tar.bz2
workbench-master.tar.lz
workbench-master.tar.xz
workbench-master.tar.zst
workbench-master.zip
add unity testing fmwk and simple hash fn demonstrationHEADmaster
Diffstat (limited to '')
-rw-r--r--src/algo/hash.c22
-rw-r--r--src/algo/hash.h10
-rw-r--r--src/algo/hash_test.c163
3 files changed, 195 insertions, 0 deletions
diff --git a/src/algo/hash.c b/src/algo/hash.c
new file mode 100644
index 0000000..c8ba66d
--- /dev/null
+++ b/src/algo/hash.c
@@ -0,0 +1,22 @@
+#include "hash.h"
+#include <stdint.h>
+
+uint64_t xor64_hash(uint64_t const *const bytes, size_t size) {
+ uint64_t result = 0;
+
+ while (size != 0) {
+ result ^= bytes[size - 1];
+ size--;
+ }
+
+ return result;
+}
+
+uint64_t djb2_hash(char const *const bytes, size_t size) {
+ uint64_t hash = 5381;
+ for (size_t i = 0; i < size; i++) {
+ hash = ((hash << 5) + hash) + bytes[i];
+ }
+
+ return hash;
+}
diff --git a/src/algo/hash.h b/src/algo/hash.h
new file mode 100644
index 0000000..2b168b9
--- /dev/null
+++ b/src/algo/hash.h
@@ -0,0 +1,10 @@
+#ifndef CRYPTOBENCH_SRC_ALGO_HASH_H
+#define CRYPTOBENCH_SRC_ALGO_HASH_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+uint64_t xor64_hash(uint64_t const *const bytes, size_t size);
+uint64_t djb2_hash(char const *const bytes, size_t size);
+
+#endif
diff --git a/src/algo/hash_test.c b/src/algo/hash_test.c
new file mode 100644
index 0000000..6836c22
--- /dev/null
+++ b/src/algo/hash_test.c
@@ -0,0 +1,163 @@
+#include "algo/hash.h"
+#include "unity.h"
+#include <stdint.h>
+#include <string.h>
+
+void test_xor_hash_consistency(void) {
+ uint64_t in[] = {10, 20, 30};
+
+ uint64_t actual_1 = xor64_hash(in, 3);
+ uint64_t actual_2 = xor64_hash(in, 3);
+
+ TEST_ASSERT_EQUAL_INT(actual_1, actual_2);
+}
+
+void test_xor_hash_empty_src(void) {
+ uint64_t in[] = {};
+
+ uint64_t actual = xor64_hash(in, 0);
+
+ TEST_ASSERT_EQUAL_INT(0, actual);
+}
+
+void test_xor_hash_single_byte(void) {
+ uint64_t in_1[] = {5};
+ uint64_t in_2[] = {10};
+ uint64_t in_3[] = {15};
+
+ uint64_t actual_1 = xor64_hash(in_1, 1);
+ uint64_t actual_2 = xor64_hash(in_2, 1);
+ uint64_t actual_3 = xor64_hash(in_3, 1);
+
+ TEST_ASSERT_NOT_EQUAL(actual_1, actual_2);
+ TEST_ASSERT_NOT_EQUAL(actual_1, actual_3);
+ TEST_ASSERT_NOT_EQUAL(actual_2, actual_3);
+}
+
+void test_xor_hash_is_varied(void) {
+ uint64_t in_1[] = {1, 2, 3};
+ uint64_t in_2[] = {4, 5, 6};
+ uint64_t in_3[] = {100, 200, 300};
+
+ uint64_t actual_1 = xor64_hash(in_1, 3);
+ uint64_t actual_2 = xor64_hash(in_2, 3);
+ uint64_t actual_3 = xor64_hash(in_3, 3);
+
+ TEST_ASSERT_NOT_EQUAL(actual_1, actual_2);
+ TEST_ASSERT_NOT_EQUAL(actual_1, actual_3);
+ TEST_ASSERT_NOT_EQUAL(actual_2, actual_3);
+}
+
+void test_xor_hash_permutation_collisions(void) {
+ uint64_t in_1[] = {1, 2};
+ uint64_t in_2[] = {2, 1};
+
+ uint64_t actual_1 = xor64_hash(in_1, 2);
+ uint64_t actual_2 = xor64_hash(in_2, 2);
+
+ TEST_ASSERT_EQUAL_INT(actual_1, actual_2);
+}
+void test_xor_hash_large_src(void) {
+ uint64_t large_array[100];
+ for (int i = 0; i < 100; i++) {
+ large_array[i] = i * 7 + 13;
+ }
+
+ uint64_t actual = xor64_hash(large_array, 100);
+
+ TEST_ASSERT_NOT_EQUAL(0, actual);
+
+ uint64_t actual_2 = xor64_hash(large_array, 100);
+ TEST_ASSERT_EQUAL_INT(actual, actual_2);
+}
+void test_xor_hash_range(void) {
+ uint64_t in[] = {10, 20, 30, 40, 50};
+
+ uint64_t hash_1 = xor64_hash(in, 1);
+ uint64_t hash_2 = xor64_hash(in, 2);
+ uint64_t hash_3 = xor64_hash(in, 3);
+ uint64_t hash_5 = xor64_hash(in, 5);
+
+ TEST_ASSERT_NOT_EQUAL(hash_1, hash_2);
+ TEST_ASSERT_NOT_EQUAL(hash_2, hash_3);
+ TEST_ASSERT_NOT_EQUAL(hash_3, hash_5);
+}
+
+void test_djb2_hash_consistency(void) {
+ const char *str = "Hello World!";
+ uint64_t actual_1 = djb2_hash(str, strlen(str));
+ uint64_t actual_2 = djb2_hash(str, strlen(str));
+
+ TEST_ASSERT_EQUAL_UINT64(actual_1, actual_2);
+}
+
+void test_djb2_hash_empty_string(void) {
+ const char *str = "";
+ uint64_t actual = djb2_hash(str, strlen(str));
+
+ TEST_ASSERT_EQUAL_UINT64(5381, actual);
+}
+
+void test_djb2_hash_single_char(void) {
+ uint64_t hash_a = djb2_hash("a", 1);
+ uint64_t hash_b = djb2_hash("b", 1);
+ uint64_t hash_z = djb2_hash("z", 1);
+
+ TEST_ASSERT_NOT_EQUAL(hash_a, hash_b);
+ TEST_ASSERT_NOT_EQUAL(hash_b, hash_z);
+}
+
+void test_djb2_hash_known_values(void) {
+ // Pre-calculated djb2 hashes:
+ // e.g. "a": (5381 * 33) + 'a' = 177573 + 97 = 177670
+ TEST_ASSERT_EQUAL_UINT64(0x0002b606ULL, djb2_hash("a", 1));
+ TEST_ASSERT_EQUAL_UINT64(0x0b887389ULL, djb2_hash("foo", 3));
+ TEST_ASSERT_EQUAL_UINT64(0x310D4F2079ULL, djb2_hash("Hello", 5));
+}
+
+void test_djb2_hash_different_strings(void) {
+ const char *str1 = "apple";
+ const char *str2 = "banana";
+ const char *str3 = "orange";
+
+ uint64_t hash1 = djb2_hash(str1, strlen(str1));
+ uint64_t hash2 = djb2_hash(str2, strlen(str2));
+ uint64_t hash3 = djb2_hash(str3, strlen(str3));
+
+ TEST_ASSERT_NOT_EQUAL(hash1, hash2);
+ TEST_ASSERT_NOT_EQUAL(hash1, hash3);
+ TEST_ASSERT_NOT_EQUAL(hash2, hash3);
+}
+
+void test_djb2_hash_large_string(void) {
+ char long_str[256];
+ for (int i = 0; i < 255; i++) {
+ long_str[i] = 'A' + (i % 26);
+ }
+ long_str[255] = '\0';
+
+ uint64_t actual = djb2_hash(long_str, strlen(long_str));
+ TEST_ASSERT_NOT_EQUAL(5381, actual);
+ TEST_ASSERT_NOT_EQUAL(0, actual);
+
+ uint64_t actual_2 = djb2_hash(long_str, strlen(long_str));
+ TEST_ASSERT_EQUAL_UINT64(actual, actual_2);
+}
+
+void test_runner_algo_hash(void) {
+ RUN_TEST(test_xor_hash_consistency);
+ RUN_TEST(test_xor_hash_empty_src);
+ RUN_TEST(test_xor_hash_single_byte);
+ RUN_TEST(test_xor_hash_is_varied);
+ RUN_TEST(test_xor_hash_permutation_collisions);
+ RUN_TEST(test_xor_hash_large_src);
+ RUN_TEST(test_xor_hash_range);
+
+ RUN_TEST(test_djb2_hash_consistency);
+ RUN_TEST(test_djb2_hash_empty_string);
+ RUN_TEST(test_djb2_hash_single_char);
+ RUN_TEST(test_djb2_hash_known_values);
+ RUN_TEST(test_djb2_hash_different_strings);
+ RUN_TEST(test_djb2_hash_large_string);
+ return;
+}