/*this method takes in a key and the cipher text, * and performs every possible column swap, and returns * the one which corresponds to the highest score*/ public static char[][] FindBestCol(char[][] child, string cipher, double[,] bookDigraph) { Digraph digraphCipher = new Digraph(); double childScore = Result.FinalScoreMult(digraphCipher.NormalisedPairCount(Decryption.Result(cipher, child)), bookDigraph); char[][] temp = Key.RandKey(Key.randAlphabet()); //Initialises random new key double tempScore = 0; for (int col_a = 0; col_a < 5; col_a++) { for (int col_b = 0; col_b < 5; col_b++) { temp = SwapSpecificCol(col_a, col_b, child); //swap columns tempScore = Result.FinalScoreMult(digraphCipher.NormalisedPairCount(Decryption.Result(cipher, temp)), bookDigraph); if (tempScore > childScore) { childScore = tempScore; //childScore is always the highest score in this method } else { temp = SwapSpecificCol(col_a, col_b, child); //Swap columns back } child = temp; //child always set to the best score } } return child; }
/*this method takes in a key and the cipher text, * and performs every possible row swap, and returns * the one which corresponds to the highest score*/ public static char[][] FindBestRow(char[][] child, string cipher, double[,] bookDigraph) { Digraph digraphCipher = new Digraph(); char[][] temp = Key.RandKey(Key.randAlphabet()); string decryptedText = Decryption.Result(cipher, temp); //generates decoded message to be used to create digraph double[,] decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //creates digraph to be used to find score double tempScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the temp key decryptedText = Decryption.Result(cipher, child); //generates decoded message to be used to create digraph decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //creates digraph to be used to find score double childScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the child key for (int row_a = 0; row_a < 5; row_a++) { for (int row_b = 0; row_b < 5; row_b++) { temp = SwapSpecificRow(row_a, row_b, child); //swap rows decryptedText = Decryption.Result(cipher, temp); //decrypts cipher decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //finds digraph for decrypted txt tempScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //finds the new score of the temp key if (tempScore > childScore) { childScore = tempScore; //childScore is always the highest score } else { temp = SwapSpecificRow(row_a, row_b, child); //Swap rows back } child = temp; //child always set to the best score } } return child; }
// <operation> <key> <plaintext address> <destination address> <= for encrypt // <operation> <plaintext address> <destination address> <= for digraph // <operation> <book digraph address> <cipher address> <= for crack static void Main(string[] args) { try //try catch to manage exceptions. If any exceptions are thrown, they are picked up in catch by exception handler 'e'. { if (args[0][0] == 'E' || args[0][0] == 'e') //checks if first arg begins with e. If so, runs encrypt { string key = args[1]; //key passed in second argument char[][] keyArray = Key.RandKey(key); //converts key as string into array string plain_text = File.ReadAllText(args[2]); //reads in plain text Console.WriteLine("You typed in the following key:" + key); string paddedText = Preprocessor.Pad(Preprocessor.Prepare(plain_text)); //prepares text for digraph analysis string encrypted_plain_text = Encryption.Result(paddedText, keyArray); //encrypts user defined text with user defined key (keyArray) Console.WriteLine("Your key:"); PrintKey(keyArray); Console.WriteLine("Encrypted text: " + encrypted_plain_text); File.WriteAllText(args[3], encrypted_plain_text); //Writes encrypted text to a user-defined directory } else if (args[0][0] == 'D' || args[0][0] == 'd') //checks if first arg begins with d. If so, runs digraph { Digraph newDigraph = new Digraph(); //creates a new digraph string plain_text = File.ReadAllText(args[1]); //reads in plain text from user defined directory string padded_plain_text = Preprocessor.Pad(Preprocessor.Prepare(plain_text)); //prepares plain text for digraph analysis double[,] digraph = newDigraph.PairCount(padded_plain_text); //creates digraph for plain text try { Console.WriteLine("This is your digraph: "); Console.WriteLine(Digraph.Print(digraph)); WriteDigraph(args[2], digraph); //writes digraph to user defined directory as .dig file Console.WriteLine("Digraph written to " + args[2]); } catch (Exception eDigraph) //handles writing exceptions, i.e. cannot write to directory { Console.WriteLine("Cannot write digraph!"); Console.WriteLine("Error:" + eDigraph.Message); } } else if (args[0][0] == 'C' || args[0][0] == 'c') //checks if first arg begins with c. If so, runs crack { string cipher = File.ReadAllText(args[2]); //reads cipher text from user defined directory Console.WriteLine("Length of cipher: " + cipher.Length); double[,] bookDigraph = ReadDigraph(args[1]); //Loads digraph from second argument Console.WriteLine("Your loaded digraph: "); Console.WriteLine(Digraph.Print(bookDigraph)); //Prints digraph from second argumen var parent = Key.RandKey(Key.randAlphabet()); //Initialises parent var child = Key.RandKey(Key.randAlphabet()); //Initialises child Digraph digraphCipher = new Digraph(); Console.WriteLine(Convert.ToChar(7)); //Sound to indicate end of loading sequence double parentScore; //definitions int cycle = 0; end = false; addressUser = true; while (!end) { string decryptedText = Decryption.Result(cipher, parent); //decrypts cipher according to parent key double[,] decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //creates digraph of decrypted cipher parentScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //creates score of user-defined cipher digraph child = Key.RandKey(Key.randAlphabet()); //makes new random key parent = Crack.ReturnSoln(child, cipher, bookDigraph); //IMPORTANT: Should return solution - NOT WORKING PROPERLY, but still some functionality decryptedText = Decryption.Result(cipher, parent); //decrypts according to parent key decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //creates digraph according to parent key parentScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //calculates score from this digraph while (addressUser) //loop for checking if finished { if (parentScore > 100000000) //number should be value of parentScore which indicates a solution has been found { end = true; //ends crack state } else { CheckDoneCrack(cipher, parent); //asks user whether solution is correct } } cycle++; //increments cycle File.WriteAllText("crack.sol", decryptedText); Console.WriteLine("The decrypted text has been saved as: crack.sol."); } } } catch(Exception e) //exteption handler e handles exceptions { Console.WriteLine("There has been an error!"); Console.WriteLine("Error:" + e.Message); //prints exception onto console } Console.WriteLine("Program finished"); Console.WriteLine(Convert.ToChar(7)); Console.WriteLine(Convert.ToChar(7)); //Sound to signify end of program Console.ReadKey(); }
public static char[][] ReturnSoln(char[][] child, string cipher, double[,] bookDigraph) { bool end = false; Digraph childDigraph = new Digraph(); string newDecMsg = Decryption.Result(cipher, child); double[,] newDecMsgDigraph = childDigraph.NormalisedPairCount(newDecMsg); int cycle_ReturnSoln = 0; char[][] temp = Key.RandKey(Key.randAlphabet()); double childScore = Result.FinalScoreMult(newDecMsgDigraph, bookDigraph); while (!end) /*In this while loop, I chose to call methods to perform each function, as opposed to having all the operations being internal. This meant that the method was easiers to test, maintain and understand.*/ { Console.WriteLine("childScore in ReturnSoln: " + childScore + "cycle_ReturnSoln" + cycle_ReturnSoln); Console.WriteLine("temp key: "); Program.PrintKey(temp); //Prints temp key Console.WriteLine("child key: "); Program.PrintKey(child); //Prints child key temp = SwapAllPairs(child, cipher, bookDigraph); //Swaps all possible pairs child = temp; newDecMsg = Decryption.Result(cipher, child); //generates decoded message to be used to create digraph newDecMsgDigraph = childDigraph.NormalisedPairCount(newDecMsg); //creates digraph to be used to find score childScore = Result.FinalScoreMult(newDecMsgDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the child key temp = FindBestRow(child, cipher, bookDigraph); //swap all rows and returns best child = temp; temp = SwapAllPairs(child, cipher, bookDigraph); //Swaps all possible pairs child = temp; newDecMsg = Decryption.Result(cipher, child); //generates decoded message to be used to create digraph newDecMsgDigraph = childDigraph.NormalisedPairCount(newDecMsg); //creates digraph to be used to find score childScore = Result.FinalScoreMult(newDecMsgDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the child key temp = FindBestCol(child, cipher, bookDigraph); //swap all columns and returns best child = temp; temp = SwapAllPairs(child, cipher, bookDigraph); //Swaps all possible pairs child = temp; newDecMsg = Decryption.Result(cipher, child); //generates decoded message to be used to create digraph newDecMsgDigraph = childDigraph.NormalisedPairCount(newDecMsg); //creates digraph to be used to find score childScore = Result.FinalScoreMult(newDecMsgDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the child key cycle_ReturnSoln++; if (childScore > 100000000) //checks to see if score is good enough to assume correct key { end = true; } if (cycle_ReturnSoln > 10) { temp = Key.RandKey(Key.randAlphabet()); //sets temp equal to new random key cycle_ReturnSoln = 0; } } return child; }
//Always returns the best pair swap public static char[][] SwapAllPairs(char[][] child, string cipher, double[,] bookDigraph) { Digraph digraphCipher = new Digraph(); int col_a = 1, col_b = 0, row_a = 0, row_b = 0; char[][] temp = child; double tempScore = Result.FinalScoreMult(digraphCipher.NormalisedPairCount(Decryption.Result(cipher, temp)), bookDigraph); string decryptedText; double[,] decryptedTextDigraph; decryptedText = Decryption.Result(cipher, child); //generates decoded message to be used to create digraph decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //creates digraph to be used to find score double childScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //calculates the score of child to be used to analyse the quality of the child key /*the for loop below swaps every possible combination of letter swaps and keeps the combination which gives the best score*/ for (col_a = 0; col_a < 5; col_a++) { for (row_a = 0; row_a < 5; row_a++) { for (col_b = 0; col_b < 5; col_b++) { for (row_b = 0; row_b < 5; row_b++) { temp = SwapPair(row_a, col_a, row_b, col_b, child); //makes swap on specific paire decryptedText = Decryption.Result(cipher, temp); //decrypts cipher decryptedTextDigraph = digraphCipher.NormalisedPairCount(decryptedText); //finds digraph for decrypted txt tempScore = Result.FinalScoreMult(decryptedTextDigraph, bookDigraph); //finds the new score of the temp key if ((tempScore > childScore)) { childScore = tempScore; //childScore is always the highest score } else { temp = SwapPair(row_a, col_a, row_b, col_b, child); //Swap back } child = temp; //Child always set to the best score } } } } return child; }