static bool DecryptWithKnownPlainAndCipherText() { Console.WriteLine("Starting crypto analysis by using known plain and cipher text."); // Convert plain text and cipher text to numbers. IEnumerable <int> valuesOfPlainText = Utilities.GetValueArray(plainText); IEnumerable <int> valuesOfCipherText = Utilities.GetValueArray(cipherText); // Store all the shift values int[] values = new int[plainText.Length]; for (int i = 0; i < plainText.Length; i++) { // Calculate each shift value between plain text and cipher text according to Vigenere cipher. values[i] = ((valuesOfCipherText.ElementAt(i) + 26) - valuesOfPlainText.ElementAt(i)) % 26; } // Create the long keyword text from obtained shift values. string longKeyword = Utilities.GetString(values); // Try to figure out the shortest key possible, i.e find out the repeating text in the long keyword text. int blockSize = 1; while (blockSize++ <= Constants.MAX_BLOCK_SIZE) { List <string> dividedKeyword = VigenereAnalyser.DivideCipherText(longKeyword, blockSize); // If a divided keywords all characters are the same, break out of the loop. bool allSame = dividedKeyword.TrueForAll(k => k.Distinct().Count() == 1); if (allSame) { break; } } if (blockSize >= Constants.MAX_BLOCK_SIZE) { // Found keyword's size is equal to the size of the plain text, obtained keyword cannot be correct. Console.WriteLine("Found cipher key's length is equal to the cipher text's length. Cipher key couldn't be found!"); return(false); } else { // Get the actual keyword. keywordText = longKeyword.Substring(0, blockSize); Console.WriteLine($"Cipher key: {keywordText}"); return(true); } }
static bool DecryptWithKnownCipherText() { Console.WriteLine("Starting crypto analysis by using only known cipher text."); // Convert ciphertext to numbers. IEnumerable <int> valuesOfCipherText = Utilities.GetValueArray(cipherText); // Apply Index of Coincidence analysis to find out the block size. int blockSize = VigenereAnalyser.FindBlockSizeWithCoincidence(cipherText); // If block size is -1, return false to signify the known cipher text analysis has failed. if (blockSize == -1) { Console.WriteLine("Crypto analysis by using only known cipher text failed to obtain block size."); return(false); } // Divide cipher texts according to the found block size. IEnumerable <string> dividedCipherTexts = VigenereAnalyser.DivideCipherText(cipherText, blockSize); // For each divided cipher text, apply frequency analysis to find out the shift amount. Store shift amounts for each divided cipher text. int[] shiftAmounts = new int[blockSize]; for (int i = 0; i < blockSize; i++) { int shiftAmount = FrequencyAnalyser.FindShiftAmount(dividedCipherTexts.ElementAt(i)); // If shift amount is -1, return false to signify the known cipher text analysis has failed. if (shiftAmount == -1) { Console.WriteLine("Crypto analysis by using only known cipher text failed to obtain shift amount."); return(false); } shiftAmounts[i] = shiftAmount; } // Obtain keyword string from shift values. keywordText = Utilities.GetString(shiftAmounts); Console.WriteLine($"Cipher key: {keywordText}"); return(true); }