/// <summary> /// Wanted to come up with a value that I could use to tell which frequencylist would be a better solution so, /// the greater the number returned from this, the better probability that the it's the solution /// </summary> /// /// <param name="characterFrequencyList">Frequencies to check</param> /// <param name="originalText">The text that the FrequecyList is from</param> /// /// <returns>Amount of "correctness" the FrequencyList has towards the English frequencies</returns> public double GetDifference(CharacterFrequencyList characterFrequencyList, string originalText) { double totalDiff = 0; int textLen = originalText.Length; foreach (CharacterFrequency cf in characterFrequencyList.CharacterFrequencies) //For each character frequency in the list { double myPercent = (((double)cf.Frequency / (double)textLen)) * 100; //Transform the int (amount of times it appears in the string) to a double (percentage of it's appearance) double englishFreq = freqs[cf.Character]; //Get the english frquency //Console.WriteLine("MyPercent = " + myPercent + ", English = " + englishFreq); //Take myPercent away from the englishFreq (if myPercent is close, the amount taken is less therefore the total is increased more) double differenceBetween = englishFreq - myPercent; if (englishFreq < myPercent) { differenceBetween = myPercent - englishFreq; } totalDiff += differenceBetween;//Incease the total by the difference } return(totalDiff); }
public string BruteForce(string cipherText) { StringBuilder buff = new StringBuilder(); CharacterFrequencyList frequencies = fa.AnalyseFrequency(cipherText); //Get the character frequencies CharacterFrequency probablyE = frequencies.ProbablyE; // Character that is most likly to be E CharacterFrequency probablyT = frequencies.ProbablyT; // Character that is most likly to be T int p = alphabet.GetCharacterIndex('E'); //Get the index of E int q = alphabet.GetCharacterIndex('T'); //Get the index of T int r = alphabet.GetCharacterIndex(probablyE.Character); //Get the index of the ciphered E int s = alphabet.GetCharacterIndex(probablyT.Character); //Get the index of the ciphered T int D = Mod(p - q, 26); //Work out what D is (difference) int invD = Inverse(D); //Get the multiplicative inverse /* * Working out :D * a x indexOf('E') + b = indexOf ( probablyE ) MOD 26, indexOf(e) = p, indexOf( probablyE ) = r * a x indexOf('T') + b = indexOf ( probablyT ) MOD 26, indexOf(t) = q, indexOf( probablyT ) = s * * D = p - q; * * a = D^-1 (r-s) MOD 26 * b = D^-1 (ps - qr) MOD 26 */ int a = Mod(invD * (r - s), 26); //Work out the first part of the key (a) int b = Mod(invD * ((p * s) - (q * r)), 26); //Work out the second part of the key (b) Console.WriteLine("Found key: a={0}, b={1}", a, b); buff.Append(string.Format("Key: ({0},{1}) ", a, b)); buff.Append(string.Format("\nDeciphered Text:\n{0}", Decipher(cipherText, a, b))); return(buff.ToString()); //Return the deciphered message }
}; //I'm not changing anything in the dictionary, might as well readonly /// <summary> /// Used to get the character frequencies in a string /// </summary> /// /// <param name="cipherText">The text to get the frequency of the characters for</param> /// /// <returns>CharacterFrequencyList that contains the diferent characters and their frequency in the string</returns> public CharacterFrequencyList AnalyseFrequency(string cipherText) { if (string.IsNullOrEmpty(cipherText)) //If it's null { throw new ArgumentException(string.Format("Sorry but, \"{0}\" cannot be analyised because it's null/empty", cipherText)); //Throw an exception so they know something screwed up } //Create a new list CharacterFrequencyList frequencies = new CharacterFrequencyList(); int textLen = cipherText.Length; for (int i = 0; i < textLen; i++) //Loop through all the characters in the string { char c = cipherText[i]; if (c == '\n' || char.IsWhiteSpace(c)) //If it's not a letter { continue; //Skip! } frequencies.AddTo(c); //Increase it's frequency } return(frequencies); //Return the list }