Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.10.2015, 20:47   #1
Nseries
Пользователь
 
Аватар для Nseries
 
Регистрация: 01.05.2011
Сообщений: 10
По умолчанию Взломать шифр Виженера методом частотного анализа 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 ();
		}
	}
Nseries вне форума Ответить с цитированием
Старый 05.10.2015, 20:48   #2
Nseries
Пользователь
 
Аватар для Nseries
 
Регистрация: 01.05.2011
Сообщений: 10
По умолчанию

Продолжение проекта
Код:
	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");
		}
	}
}
Nseries вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шифр Виженера (Взлом) RXK Помощь студентам 1 21.06.2015 19:25
Шифр Виженера в Delphi makson4ik Помощь студентам 2 07.05.2012 22:44
программа дешифрования криптограммы Вижинера на основе индексов соответствия и частотного анализа. КоСТиК1723 Помощь студентам 5 17.06.2010 19:48
Шифр Виженера Radiy Паскаль, Turbo Pascal, PascalABC.NET 7 12.06.2010 10:05