/* Author: Pate Williams (c) 1997 Exercise III.1.1 "In certain computer bullentin-boards systems it is customary, if you want to post a message that may offend some people (e.g. a dirty joke), to encipher the letters (but not the blanks or punctuation) by a translation C = P + b mod 26. Using frequency analysis decrypt the following ciphertext: Jr frjrq n fzvyr ba n ubefr'f nff, naq n lrne yngre vg jnf ryrpgrq Cerfvqrag!" -Neal Koblitz- See "A Course in Number Theory and Cryptography" by Neal Koblitz second edition page 61. */ #include #include struct code {long alpha, count;}; int main(void) { char cipher[3][25] = {"JRFRJRQNFZVYRBANUBEFRF", "NFFNAQNLRNEYNGREVGJNFR", "YRPGRQCERFVQRAG"}; long b, count = 0, i, j, p; long ciphertext[128], frequency[26] = {0}; struct code c[26], t; for (i = 0; i < 3; i++) { for (j = 0; j < strlen(cipher[i]); j++) { ciphertext[count] = cipher[i][j] - 'A'; frequency[ciphertext[count++]]++; } } for (i = 0; i < 26; i++) { c[i].alpha = i; c[i].count = frequency[i]; } /* sort the code array into descending order */ for (i = 0; i < 25; i++) for (j = i + 1; j < 26; j++) if (c[i].count < c[j].count) t = c[i], c[i] = c[j], c[j] = t; b = (c[0].alpha - 4) % 26; if (b < 0) b += 26; printf("the ciphertext is as follows:\n"); for (i = 0; i < count; i++) { printf("%c", ciphertext[i] + 'A'); if ((i + 1) % 25 == 0) printf("\n"); } printf("\n"); printf("the plaintext is as follows:\n"); for (i = 0; i < count; i++) { p = (ciphertext[i] - b) % 26; if (p < 0) p += 26; printf("%c", p + 'A'); if ((i + 1) % 25 == 0) printf("\n"); } printf("\n"); return 0; }