diff --git a/solutions/c/crypto-square/1/crypto_square.c b/solutions/c/crypto-square/1/crypto_square.c new file mode 100644 index 0000000..8f29f72 --- /dev/null +++ b/solutions/c/crypto-square/1/crypto_square.c @@ -0,0 +1,50 @@ +#include "crypto_square.h" +#include +#include +#include +#include +#include + +char *ciphertext(const char *input){ + if (!input) return NULL; + + size_t len = strlen(input); + char *cleaned = malloc(len); + if (!cleaned) return NULL; + + size_t count = 0; + + { + size_t i = 0; + char c; + while ((c = input[i++])) if (isalpha(c)) cleaned[count++] = tolower(c); else if (isdigit(c)) cleaned[count++] = c; + } + + if (count == 0) { + free(cleaned); + return calloc(1, 1); + } + + size_t c = ceil(sqrt(count)); + size_t r = (c * (c - 1) >= count) ? c - 1 : c; + + size_t size = c * r + (c - 1) + 1; + char *cipher = malloc(size); + if (!cipher) { free(cleaned); return NULL; } + + memset(cipher, ' ', size); + + size_t counter = 0; + for (size_t i = 0; i < c; i++) { + size_t old_counter = counter; + for (size_t j = i; j < count; j += c) { + cipher[counter++] = cleaned[j]; + } + if (counter != old_counter + r) counter = old_counter + r; + if (i < c - 1) cipher[counter++] = ' '; + } + + free(cleaned); + cipher[counter] = '\0'; + return cipher; +} diff --git a/solutions/c/crypto-square/1/crypto_square.h b/solutions/c/crypto-square/1/crypto_square.h new file mode 100644 index 0000000..b133e21 --- /dev/null +++ b/solutions/c/crypto-square/1/crypto_square.h @@ -0,0 +1,6 @@ +#ifndef CRYPTO_SQUARE_H +#define CRYPTO_SQUARE_H + +char *ciphertext(const char *input); + +#endif