/*********** First Letters Attack ************/ // TODO: ostatní jazyky nemají TopWords!!! private List<string> FirstLettersAttack(string ciphertext, Storage.Languages language) { var keyLengths = GetKeyLengths(ciphertext); int minWordLength = 3; int testStringLength = 20; double minSuccess = (double)20 / (double)1300; foreach (int keyLength in keyLengths) { if (keyLength < 10) continue; string[] columns = GetDecryptColumns(ciphertext, keyLength); string[] rows = GetRows(columns); string[] sentence = rows.Take((int)Math.Ceiling((double)testStringLength / (double)keyLength)).ToArray(); var lang = Storage.GetLangChar(language); DictionaryAttack firstAttack = new DictionaryAttack(); string[] topWords = lang.TopWords.Where(x => x.Length >= minWordLength).ToArray(); string[] topTopWords = topWords.Take(100).ToArray(); var keys = firstAttack.CrossFilter(sentence, topWords); var opentexts = new string[keys.Length]; for (int i = 0; i < keys.Length; i++) opentexts[i] = Decrypt(ciphertext, keys[i]); Dictionary<string, int> probabilities = new Dictionary<string, int>(); for (int i = 0; i < keys.Length; i++) probabilities[keys[i]] = Analyse.WordsContains(opentexts[i], topTopWords); var resultKeys = probabilities.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value); var isthere = opentexts.Where(x => x.Contains("oznamenipodala")).Count() == 1; if(resultKeys.Count > 0 && ((double)resultKeys.First().Value / (double)1300) > minSuccess) return resultKeys.Take(10).Select(x => x.Key).ToList(); } throw new Exceptions.MatchNotFound(); }
/*********************************************/ /*********** One big word attack *************/ /*********************************************/ private List<string> BigWordAttack(string ciphertext, Storage.Languages language) { ciphertext = Analyse.NormalizeText(ciphertext, Analyse.TextTypes.WithoutSpacesLower); var keyLengths = GetKeyLengths(ciphertext); LangCharacteristic lang = Storage.GetLangChar(language); List<string> possKeys = new List<string>(); foreach (int keyLength in keyLengths) { string[] columns = GetDecryptColumns(ciphertext, keyLength); string[] rows = GetRows(columns); DictionaryAttack attack = new DictionaryAttack(); string[] keys = attack.GetKeys(rows, lang.TopWords); string[] orderedKeys = OrderKeys(keys, ciphertext, lang); if (orderedKeys.Length > 0) possKeys.Add(orderedKeys[0]); } if (possKeys.Count > 0) { string[] finalKeys = OrderKeys(possKeys.ToArray(), ciphertext, lang); return finalKeys.ToList(); } throw new Exceptions.MatchNotFound(); }
/*********** test key length attack *******************/ private List<string> TestKeyLength(string ciphertext, Storage.Languages language) { int averageKeyLength = 10; int minSentenceLength = 40; var keyLengths = Maths.AllDivisors(ciphertext.Length); var orderKeyLengths = keyLengths.OrderBy(x => Math.Abs(x - averageKeyLength)).ToArray(); foreach (int keyLength in orderKeyLengths) { string[] columns = GetDecryptColumns(ciphertext, keyLength); string sentence = GetOpentext(columns).Take(minSentenceLength); var lang = Storage.GetLangChar(language); DictionaryAttack attack = new DictionaryAttack(lang.Dictionary, lang.SortedDictionary); attack.Start(sentence, keyLength); } return new List<string>() { "abc" }; }