Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
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)));
        }