/* * Solve Vigenere ciphers by frequency analysis * Program written by Fauzan Mirza, 13 Sept 1995 * 18 Sept 1995 - Bug fixed * * Based on the BSD caesar program by Stan King and John Eldridge * * For an explanation of how and why this method works refer to: * Abraham Sinkov, "Elementary Cryptanalysis", Random House, 1968. * * Usage: vigsolve < CipherTextFile * Vigenere ciphertext is taken from STDIN (may need to pipe it in) * * Added Dec 1995, Index of Coincidence, plus two additional methods, * giving keys for Vigenere, Beaufort and Variant Beaufort. Ernest Brandt * */ #include #include #include #include #ifdef __unix__ #include #else #include #define STDIN_FILENO 0 #endif #define KEYLENGTH 20 #define BUFFERLEN 4096 /* Letter frequencies (from BSD caesar) */ double stdf[26] = { 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04, 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68, 2.62, 0.81, 1.88, 0.23, 2.07, 0.06, }; void main() { int freq[KEYLENGTH][26]; int num[BUFFERLEN]; char buf[BUFFERLEN]; char key1[KEYLENGTH], key2[KEYLENGTH], key3[KEYLENGTH]; int buflen, len, try, lets; double dot, winnerdot; double dot3, winnerdot3; double icsum, ic; double lsum, nsum; int i, j; printf("\nIndex of Coincidence and Periodic Key Find\n\n"); buflen=read(STDIN_FILENO, buf, BUFFERLEN); lets = 0; for (i=0; i winnerdot) /* find max */ { key1[i] = (26-try) % 26 + 'a'; key2[i] = (try) % 26 + 'a'; winnerdot=dot; } if (dot3 > winnerdot3) /* find max */ { key3[i] = (try) % 26 + 'a'; winnerdot3=dot3; } } } key1[KEYLENGTH-1]=0; /* Terminate string */ key2[KEYLENGTH-1]=0; key3[KEYLENGTH-1]=0; icsum = 0; /* Compute Index of Coincidence */ for (i=0; i