Взломать шифр Виженера методом частотного анализа - 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);
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д