Взломать шифр Виженера методом частотного анализа - C#

Узнай цену своей работы

Формулировка задачи:

Добрый вечер, сообщество. Возникла трудная задача, необходимо взломать шифр Виженера. Основная проблема в том, что я не могу найти внятную информацию о том как это сделать и хотя бы один законченный пример. Я приведу пример своего кода, здесь я шифрую текст, расшифровываю его для проверки работы алгоритма шифрования, потом получаю длину ключевого слово методом Касиски, но дальше ничего. Может хоть кто-нибудь знает как это сделать?
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace Lab1IT
{
    public class Lab1Task1
    {
        public List<char> abc = new List<char>();
 
        public int GetIndex(char c)
        {
            for (int i = 0; i < abc.Count; i++) 
            {
                if (abc[i] == c)
                    return i;
            }
 
            return 0;
        }
 
        public int GetOffeset(char c)
        {
            return GetIndex (c) - GetIndex ('a');
        }
 
        public void InitABC()
        {
            for (int i = 97; i < 123; i++)
                abc.Add ((char)i);
//          for (int i = 1072; i < 1104; i++)
//              abc.Add ((char)i);
        }
 
        public void Encrypt (string file, string resultFile, string key)
        {
            string result = "";
            string message = System.IO.File.ReadAllText(file);
 
            key = PreapareKey (key, message);
 
            for (int i = 0; i < message.Length; i++) 
            {
                if (message [i] != ' ') 
                {
                    int index = GetIndex (message [i]);
                    int res = (index + GetIndex (key [i])) % abc.Count;
                    result += abc [res];
                }
                else
                result += ' ';
            }
 
            System.IO.File.WriteAllText (resultFile,result,System.Text.Encoding.UTF8);
            Console.WriteLine (result);
        }
 
        public void Decrypt (string file, string resultFile, string key)
        {
            string result = "";
            string message = System.IO.File.ReadAllText(file);
            
            key = PreapareKey (key, message);
 
            for (int i = 0; i < message.Length; i++) 
            {
                if (message [i] != ' ') 
                {
                    int index = GetIndex(message[i]);
                    int res = (index - GetIndex(key[i]) + abc.Count) % abc.Count;
                    result += abc[res];
                }
                else
                result += ' ';
            }
 
            System.IO.File.WriteAllText (resultFile,result,System.Text.Encoding.UTF8);
            Console.WriteLine (result);
        }
 
        public string PreapareKey(string key, string message)
        {
            string newKey = "";
            while (newKey.Length < message.Length) 
                newKey = newKey + key;
                
            if (newKey.Length < message.Length)
                newKey.Remove (message.Length);
 
            return newKey;
        }
 
        public Lab1Task1()
        {
            InitABC ();
        }
    }

    public class Lab1Task2 
    {
        public int lgramsLength = 3;
 
        public Dictionary <char,double> values = new Dictionary<char, double> ();
 
        public Lab1Task2()
        {
            values.Add ('a', 0.08167f);
            values.Add ('b', 0.01492f);
            values.Add ('c', 0.02782f);
            values.Add ('d', 0.04253f);
            values.Add ('e', 0.12702f);
            values.Add ('f', 0.02228f);
            values.Add ('g', 0.02015f);
            values.Add ('h', 0.06094f);
            values.Add ('i', 0.06966f);
            values.Add ('j', 0.00153f);
            values.Add ('k', 0.00772f);
            values.Add ('l', 0.04025f);
            values.Add ('m', 0.02406f);
            values.Add ('n', 0.06749f);
            values.Add ('o', 0.07507f);
            values.Add ('p', 0.01929f);
            values.Add ('q', 0.00095f);
            values.Add ('r', 0.05987f);
            values.Add ('s', 0.06327f);
            values.Add ('t', 0.09056f);
            values.Add ('u', 0.02758f);
            values.Add ('v', 0.00978f);
            values.Add ('w', 0.02360f);
            values.Add ('x', 0.00150f);
            values.Add ('y', 0.01974f);
            values.Add ('z', 0.00074f);
//          values.Add ('а', );
//          values.Add ('б', );
//          values.Add ('в', );
//          values.Add ('г', );
//          values.Add ('д', );
//          values.Add ('е', );
//          values.Add ('ж', );
//          values.Add ('з', );
//          values.Add ('и', );
//          values.Add ('к', );
//          values.Add ('л', );
//          values.Add ('м', );
//          values.Add ('н', );
//          values.Add ('о', );
//          values.Add ('п', );
//          values.Add ('р', );
//          values.Add ('с', );
//          values.Add ('т', );
//          values.Add ('у', );
//          values.Add ('ф', );
//          values.Add ('х', );
//          values.Add ('ц', );
//          values.Add ('ч', );
//          values.Add ('ш', );
//          values.Add ('щ', );
//          values.Add ('ъ', );
//          values.Add ('ы', );
//          values.Add ('ь', );
//          values.Add ('э', );
//          values.Add ('ю', );
//          values.Add ('я', );
        }
 
        int GCD(int a, int b)
        {
            return b == 0 ? a : GCD(b, a % b);
        }
 
        void GCD(List<int> repeatCount)
        {
            Dictionary<int,int> pairs = new Dictionary<int, int> ();
 
            Console.WriteLine (repeatCount.Count);
 
            for (int i = 0; i < repeatCount.Count; i++)
            {
                for (int j = i + 1; j < repeatCount.Count; j++) 
                {
                    int gc = GCD (repeatCount [i], repeatCount [j]);
 
                    if (gc > 1) 
                    {
                        if (pairs.ContainsKey (gc))
                            pairs [gc]++;
                        else
                            pairs.Add (gc, 1);
                    }
                }
            }
                
            var sortDict = pairs.OrderByDescending (x => x.Value).Take(5);
 
            foreach (var s in sortDict)
            {
                if(s.Value>0)
                {
                    Console.Write (s.Key + " ");
                }
            }
 
            Console.WriteLine ();
        }
 
        public void SearchLGrams(string file)
        {
            string message = System.IO.File.ReadAllText(file);
 
            List<int> repeats = new List<int>();
 
            for (int i = 0; i < message.Length - lgramsLength; i++) 
            {
                string lgram1 = message.Substring(i,lgramsLength);
 
                for (int j = i+1; j < message.Length - lgramsLength; j++) 
                {
                    string lgram2 = message.Substring(j,lgramsLength);
 
                    if (lgram1.Equals(lgram2))
                    {
                        repeats.Add (j - i);    
                    }
                }
            }
 
            GCD (repeats);
 
            string text = message.Replace(" ", string.Empty).ToLower();
            double symbolsCount = text.Length;

            SortedDictionary< char, int > dict = new SortedDictionary<char, int>();
 
            for (int i = 0; i < text.Length; i++)
                if (dict.ContainsKey(text[i]))
                    dict[text[i]]++;
                else
                    dict.Add(text[i], 1);
 
            var sortDict = dict.OrderByDescending(x => x.Value);
 
            Dictionary<char,double> resultedValues = new Dictionary<char, double> ();
 
            foreach (KeyValuePair< char, int > kvp in sortDict) 
            {
                double val = System.Math.Round((double)kvp.Value/symbolsCount,5);
                resultedValues.Add(kvp.Key,val);
                Console.WriteLine ("Символ: {0}, встречается {1} раз. Частота {2}. Дано {3}", kvp.Key,
                    kvp.Value,val,System.Math.Round((double)values[kvp.Key],5));
            }
                
        }
    }

    class MainClass
    {
        public static void Main (string[] args)
        {
            Lab1Task1 lab1Task1 = new Lab1Task1 ();
            lab1Task1.Encrypt ("/Users/Alexander/Projects/Lab1IT/Lab1IT/files/code.txt", "/Users/Alexander/Projects/Lab1IT/Lab1IT/files/encoded.txt", "abcdefg");
            lab1Task1.Decrypt ("/Users/Alexander/Projects/Lab1IT/Lab1IT/files/encoded.txt", "/Users/Alexander/Projects/Lab1IT/Lab1IT/files/decoded.txt", "abcdefg");
 
            Lab1Task2 lab1Task2 = new Lab1Task2 ();
            lab1Task2.SearchLGrams ("/Users/Alexander/Projects/Lab1IT/Lab1IT/files/encoded.txt");
        }
    }
}

Решение задачи: «Взломать шифр Виженера методом частотного анализа»

textual
Листинг программы
        for (int j = 0; j < (message.Length / keyLength)+1; j++)
                    if (dict.ContainsKey(strings[j,i]))
                        dict[strings[j,i]]++;
                    else
                        dict.Add(strings[j,i], 1);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4 из 5
Похожие ответы