/// <summary> /// Finds the most suitable key for the given text /// The key may not be 100% compatible as there may be some character that is not in the alphabet /// </summary> /// <param name="text">String containing all the text from the file</param> /// <returns>The key value</returns> private static Int32 FindKey(String text) { // splits the text into an array using the whitespace and newline as separator. var words = text.Split(new char[] { Whitespace, '\r', '\n' }) .Where(word => word != string.Empty).ToArray(); int matchNumber = -1; // this will store the number of words that match from the best key at the time int matchKey = -1; //the number of possible keys is the length of the alphabet for (int i = 0; i <= Alphabet.Length; i++) { //this code uses the length of the alphabet as key and tests the number of completely valid english words for the given key int wordsMatched = 0; //checks only untill reaches the end of the text or the NumCheckWords variable for (var j = 0; j < words.Length && j < NumCheckWords; j++) { var word = ReplaceWithKey(words[j], i); if (word.Length > 0 && _spell.TestWord(word)) { wordsMatched++; } } if (wordsMatched > matchNumber) { matchNumber = wordsMatched; matchKey = i; } } return(matchKey); }
public static String decode(String cipher) { //decodes with the Caesar cipher List <object> retList = establishVariables(); cipher = cipher.ToLower(); String alphabet = Convert.ToString(retList[0]); Dictionary <char, int> characterToInteger = retList[1] as Dictionary <char, int>; Dictionary <int, char> integerToCharacter = retList[2] as Dictionary <int, char>; char[] cipherText = cipher.ToCharArray(); //so we have a permanent copy char[] guessText = cipher.ToCharArray(); //this will be manipulated int iter = 0; bool found = false; // when to break out of the while loop while (iter <= 25) { // constructs the shift "guess" var textList = new List <char>(); foreach (char elem in guessText) { if (alphabet.Contains(elem.ToString())) { int val = characterToInteger[elem]; val = (val + iter) % 26; //performs shift textList.Add(integerToCharacter[val]); } else { textList.Add(elem); } } String result = MakeString(textList); string[] strRes = result.Split(' '); // checks to see if NetSpell is working correctly NetSpell.SpellChecker.Dictionary.WordDictionary oDict = new NetSpell.SpellChecker.Dictionary.WordDictionary(); String path = "..//..//en-US.dic"; oDict.DictionaryFile = path; oDict.Initialize(); NetSpell.SpellChecker.Spelling oSpell = new NetSpell.SpellChecker.Spelling(); oSpell.Dictionary = oDict; // checks to see if the guess is proper English by at least 50% double englishThreshold = 0.5; int sizeOfGuess = strRes.Length; int properEnglishCount = 0; foreach (String current in strRes) { if (oSpell.TestWord(current)) { properEnglishCount++; } double thresholdCheck = (double)properEnglishCount / (double)sizeOfGuess; if (thresholdCheck >= englishThreshold) { int shiftValue = 26 - iter; found = true; } } if (found == true) { return(result); } //iterates the while iter++; } return("I'm sorry, indecipherable with a shift cipher."); }
public static String decode(String cipherText) { List <object> retList = establishVariables(); cipherText = cipherText.ToLower(); String alphabet = Convert.ToString(retList[0]); Dictionary <char, int> characterToInteger = retList[1] as Dictionary <char, int>; Dictionary <int, char> integerToCharacter = retList[2] as Dictionary <int, char>; for (int i = 1; i <= 26; i++) { //Iterate through all possible "a" values int inverse = calculateInverse(i); if (inverse == 0 || i == 13) { // This value of a has no inverse, skip } else { for (int b = 0; b <= 26; b++) { //iterate through all possible "b" values var cipherTextGuess = new List <char>(); foreach (char letter in cipherText) { if (alphabet.Contains(letter.ToString())) { int value = characterToInteger[letter]; int affineValue = (inverse * (value - b)) % 26; //perform affine calculation if (affineValue < 0) { affineValue = affineValue + 26; } char charValue = integerToCharacter[affineValue]; cipherTextGuess.Add(charValue); } else { cipherTextGuess.Add(letter); } } String guess = MakeString(cipherTextGuess); string[] strRes = guess.Split(' '); NetSpell.SpellChecker.Dictionary.WordDictionary oDict = new NetSpell.SpellChecker.Dictionary.WordDictionary(); String path = "..//..//en-US.dic"; oDict.DictionaryFile = path; oDict.Initialize(); NetSpell.SpellChecker.Spelling oSpell = new NetSpell.SpellChecker.Spelling(); oSpell.Dictionary = oDict; // checks to see if the guess is proper English by at least 60% double englishThreshold = 0.6; int sizeOfGuess = strRes.Length; int properEnglishCount = 0; foreach (String current in strRes) { if (oSpell.TestWord(current)) { properEnglishCount++; } double thresholdCheck = (double)properEnglishCount / (double)sizeOfGuess; if (thresholdCheck >= englishThreshold) { //if threshold met, return guess return(guess); } } } } } return("I'm sorry, indecipherable cipher."); }