예제 #1
0
        /// <summary>
        /// Friedman test
        /// </summary>
        /// <param name="ciphertext"></param>
        /// <param name="language"></param>
        /// <param name="results"></param>
        /// <param name="maxKeyLength"></param>
        /// <returns></returns>
        public static int FriedmanTest(string ciphertext, string language, out Dictionary <int, List <double> > results, int maxKeyLength = 16)
        {
            results = new Dictionary <int, List <double> >();
            double languageIdc        = Vigenere.LETTER_FREQUENCY[language].IndexOfCoincidence;
            double average            = 0;
            double probableKeyAverage = 0;
            int    probableKeyLength  = 0;

            for (int keyLength = 2; keyLength <= maxKeyLength; keyLength++)
            {
                average = 0;

                results[keyLength] = new List <double>();

                for (int offset = 0; offset < keyLength; offset++)
                {
                    double idc = Vigenere.IndexOfCoincidence(ciphertext, offset, keyLength);
                    results[keyLength].Add(idc);
                    average += idc;
                }

                average = average / keyLength;

                if (Math.Abs(languageIdc - average) < Math.Abs(languageIdc - probableKeyAverage))
                {
                    probableKeyLength  = keyLength;
                    probableKeyAverage = average;
                }
            }

            return(probableKeyLength);
        }
예제 #2
0
        private void btnRunFriedman_Click(object sender, EventArgs e)
        {
            if (this.txtCiphertext.Text == string.Empty)
            {
                MessageBox.Show(this, "The ciphertext message must be defined!", "Error");
            }
            else
            {
                string ciphertext = this.txtCiphertext.Text.Replace(" ", string.Empty).Replace("\n", string.Empty).Replace("\r", string.Empty);

                StringBuilder sb = new StringBuilder();
                Dictionary <int, List <double> > friedmanResults;
                int probableKeyLength = Vigenere.FriedmanTest(ciphertext, this.cbbLanguage.Text, out friedmanResults, (int)this.nudMaxKeyLength.Value);

                sb.Append("Key length : IC(x)\r\n");

                foreach (KeyValuePair <int, List <double> > friedmanResult in friedmanResults)
                {
                    sb.Append(friedmanResult.Key + " :");

                    foreach (double value in friedmanResult.Value)
                    {
                        sb.Append(" " + Math.Round(value, 3));
                    }

                    sb.Append("\r\n");
                }

                this.txtResultFriedman.Text             = sb.ToString();
                this.txtProbableKeyLength.Text          = probableKeyLength.ToString();
                this.nudAnalyseFrequencyKeyLength.Value = probableKeyLength;
            }
        }
예제 #3
0
        /// <summary>
        /// Guess key
        /// </summary>
        /// <param name="ciphertext"></param>
        /// <param name="keyLength"></param>
        /// <returns></returns>
        public static string GuessKey(string ciphertext, int keyLength, string language)
        {
            char[] key           = new char[keyLength];
            int    numberLetters = Vigenere.LETTER_FREQUENCY[language].NumberOfLetters;

            // METHOD 1 : Using language frequency for mutual indices of coincidence for all cipher vectors
            for (int offset = 0; offset < keyLength; offset++)
            {
                double[] indices     = new double[numberLetters];
                double[] frequencies = Vigenere.Frenquencies(ciphertext, offset, keyLength).Select(Convert.ToDouble).ToArray();

                indices = Vigenere.MutualIndicesOfCoincidence(Vigenere.LETTER_FREQUENCY[language].LetterFrequencies, 1, frequencies, frequencies.Sum());

                int bestShift = 0;
                for (int shift = 1; shift < numberLetters; shift++)
                {
                    if (indices[shift] > indices[bestShift])
                    {
                        bestShift = shift;
                    }
                }

                key[offset] = (char)(bestShift + 65);
            }

            // METHOD 2 : Using reference vector for mutual indices of coincidence for all other cipher vectors

            /*double[] frequenciesLang = Vigenere.LETTER_FREQUENCY[language].LetterFrequencies;
             * double[] frequenciesRef = Vigenere.Frenquencies(ciphertext, 0, keyLength).Select(Convert.ToDouble).ToArray();
             * double lengthRef = frequenciesRef.Sum();
             *
             * double[] indices = new double[numberLetters];
             * indices = Vigenere.MutualIndicesOfCoincidence(frequenciesLang, 1, frequenciesRef, lengthRef);
             *
             * int shiftRef = 0;
             * for (int i = 1; i < numberLetters; i++)
             *  if (indices[i] > indices[shiftRef])
             *      shiftRef = i;
             *
             * key[0] = (char)(shiftRef + 65);
             *
             * for (int offset = 1; offset < keyLength; offset++)
             * {
             *  double[] frequenciesCmp = Vigenere.Frenquencies(ciphertext, offset, keyLength).Select(Convert.ToDouble).ToArray();
             *  double lengthCmp = frequenciesRef.Sum();
             *
             *  indices = Vigenere.MutualIndicesOfCoincidence(frequenciesRef, lengthRef, frequenciesCmp, lengthCmp);
             *
             *  int bestShift = 0;
             *  for (int i = 1; i < numberLetters; i++)
             *      if (indices[i] > indices[bestShift])
             *          bestShift = i;
             *
             *  key[offset] = (char)((bestShift + shiftRef) % numberLetters + 65);
             * }*/

            return(new string(key));
        }
예제 #4
0
        private void btnAnalyseFrequency_Click(object sender, EventArgs e)
        {
            if (this.txtCiphertext.Text == string.Empty)
            {
                MessageBox.Show(this, "The ciphertext message must be defined!", "Error");
            }
            else
            {
                string ciphertext = this.txtCiphertext.Text.Replace(" ", string.Empty).Replace("\n", string.Empty).Replace("\r", string.Empty);

                this.txtAnalyseFrequenciesKey.Text = Vigenere.GuessKey(ciphertext, (int)this.nudAnalyseFrequencyKeyLength.Value, this.cbbLanguage.Text);
                this.txtKey.Text = this.txtAnalyseFrequenciesKey.Text;
            }
        }
예제 #5
0
        /// <summary>
        /// Calculate index of coincidence
        /// </summary>
        /// <param name="ciphertext"></param>
        /// <param name="offset"></param>
        /// <param name="keyLength"></param>
        /// <returns></returns>
        private static double IndexOfCoincidence(string ciphertext, int offset, int keyLength, int numberLetters = 26)
        {
            double index  = 0;
            int    length = 0;

            int[] frequences = Vigenere.Frenquencies(ciphertext, offset, keyLength);

            for (int k = 0; k < numberLetters; k++)
            {
                index  += frequences[k] * (frequences[k] - 1);
                length += frequences[k];
            }

            return(index / (length * (length - 1)));
        }
예제 #6
0
 private void btnDecrypt_Click(object sender, EventArgs e)
 {
     if (this.txtCiphertext.Text == string.Empty)
     {
         MessageBox.Show(this, "The ciphertext message must be defined!", "Error");
     }
     else if (this.txtKey.Text == string.Empty)
     {
         MessageBox.Show(this, "The key must be defined!", "Error");
     }
     else
     {
         this.txtCleartext.Text = Vigenere.Decrypt(this.txtCiphertext.Text, this.txtKey.Text);
     }
 }
예제 #7
0
 /// <summary>
 /// Decrypt the ciphertext message
 /// </summary>
 /// <param name="ciphertext"></param>
 /// <param name="key"></param>
 /// <returns></returns>
 public static string Decrypt(string ciphertext, string key)
 {
     return(Vigenere.ProcessKey(ciphertext, key, -1));
 }
예제 #8
0
 /// <summary>
 /// Encrypt the cleartext message
 /// </summary>
 /// <param name="cleartext"></param>
 /// <param name="key"></param>
 /// <returns></returns>
 public static string Encrypt(string cleartext, string key)
 {
     return(Vigenere.ProcessKey(cleartext, key, 1));
 }