From 6aec103b134f3229e3b0329508c9bd5bd423e880 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Sat, 4 Apr 2015 20:34:17 +0200 Subject: guesskeylength: Calculates indices of coincidence for different key width possibilities. --- guesskeylength.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 guesskeylength.c diff --git a/guesskeylength.c b/guesskeylength.c new file mode 100644 index 0000000..7941a93 --- /dev/null +++ b/guesskeylength.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +#define CTOI(c) ((c) - 'A') +#define ITOC(c) ((c) + 'A') + +#define ALPHACHARS 26 + +void preprocess(char *str) +{ + char *src = str, *dest = str; + + while (*src != '\0') { + if (isalpha(*src)) + *(dest++) = toupper(*src); + src++; + } + + *dest = '\0'; +} + +double calc_ic_column(const char *text, size_t length, size_t offset, size_t spacing) +{ + unsigned foundc[ALPHACHARS] = {0}, total_chars = 0; + unsigned long pre_sum = 0; + + for (size_t i = offset; i < length; i += spacing, total_chars++) + foundc[CTOI(text[i])]++; + + for (unsigned i = 0; i < ALPHACHARS; i++) + pre_sum += foundc[i] * (foundc[i] - 1); + + return (double)pre_sum / ((double)total_chars * (double)(total_chars - 1) / ALPHACHARS); +} + +double calc_ic(const char *text, size_t length, size_t width) +{ + double total = 0; + + for (size_t offset = 0; offset < width; offset++) + total += calc_ic_column(text, length, offset, width); + + return total / width; +} + +int main(int argc, char **argv) +{ + char *text; + size_t length; + unsigned long max; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \a\n", argv[0]); + exit(EXIT_FAILURE); + } + + text = argv[1]; + max = strtoul(argv[2], NULL, 10); + + preprocess(text); + length = strlen(text); + + for (unsigned long spacing = 1; spacing <= max; spacing++) { + double ic = calc_ic(text, length, spacing); + unsigned barlen; + + if (ic > 0.8 && ic < 4) + barlen = (ic - 0.8) / 3.2 * 40.0; + else + barlen = ic <= 0.8 ? 0 : 40; + + printf("%3lu - %6.3f ", spacing, ic); + for (unsigned i = 0; i < barlen; i++) + putchar('#'); + putchar('\n'); + } + + return EXIT_SUCCESS; +} -- cgit v1.2.3-54-g00ecf