/// <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);
        }
示例#2
0
    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.");
    }
示例#3
0
    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.");
    }