From c81c8bfa3cdcf805bce8a7fa5f3b24633a617edc Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Sat, 4 May 2024 11:35:54 -0700 Subject: [PATCH] hamming distance --- docs/crypto.md | 8 ++++++++ include/lfcrypto.h | 2 ++ src/crypto.c | 22 ++++++++++++++++++++++ tests/tests.c | 3 +++ 4 files changed, 35 insertions(+) diff --git a/docs/crypto.md b/docs/crypto.md index 2d81ab2..d993427 100644 --- a/docs/crypto.md +++ b/docs/crypto.md @@ -89,3 +89,11 @@ responsible for freeing the returned array ```c const unsigned char *repeating_key_xor_s(const char* s, const char* key); ``` + +### hamming_distance + +Calculates the Hamming Distance (the number of differing bits) between two strings + +```c +unsigned int hamming_distance(const char *a, const char *b); +``` diff --git a/include/lfcrypto.h b/include/lfcrypto.h index 624e776..7492841 100644 --- a/include/lfcrypto.h +++ b/include/lfcrypto.h @@ -13,4 +13,6 @@ const char *hex_to_str(const unsigned char *hex, size_t sz); const unsigned char* repeating_key_xor(const unsigned char* s, size_t s_sz, const unsigned char* key, size_t k_sz); const unsigned char *repeating_key_xor_s(const char* s, const char* key); +unsigned int hamming_distance(const char *a, const char *b); + #endif // LIBFLINT_CRYPTO_H diff --git a/src/crypto.c b/src/crypto.c index 6763656..ac04bdf 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -271,3 +271,25 @@ const unsigned char* repeating_key_xor(const unsigned char* s, size_t s_sz, cons const unsigned char *repeating_key_xor_s(const char* s, const char* key) { return repeating_key_xor((unsigned char*)s, strlen(s), (unsigned char*)key, strlen(key)); } + +unsigned int hamming_distance(const char *a, const char *b) { + size_t sz = strlen(a); + if (sz != strlen(b)) { + return -1; + } + + unsigned int hamming = 0; + for (size_t i = 0; i < sz; ++i) { + if (a[i] == b[i]) { + continue; + } + unsigned char c = a[i] ^ b[i]; + unsigned int count = 0; + for (; c; count++) { + c &= c - 1; + } + hamming += count; + } + + return hamming; +} diff --git a/tests/tests.c b/tests/tests.c index c18badf..e8d4ddf 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -374,6 +374,9 @@ void test_crypto() { free(enc); free(s); + unsigned int hamming = hamming_distance("this is a test", "wokka wokka!!!"); + assert(hamming == 37); + printf("Passes all crypto tests\n"); }