using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExtensionMethods;
namespace CryptanalysisCore
{
class LetterProperties
{
///
/// Symetrické bigramy, které se nachází v nejčastějších bigramech
///
public readonly string[] SymetricBigramsInTop;
public readonly string[] BigramsWithLetter;
public readonly string[] TrigramsWithLetter;
public readonly int LettersBefore;
public readonly int LettersAfter;
public readonly char Letter;
public int SimilarityIndex(LetterProperties letprop)
{
int index = 0;
index += Math.Abs(SymetricBigramsInTop.Length - letprop.SymetricBigramsInTop.Length);
/*index += Math.Abs(BigramsWithLetter.Length - letprop.BigramsWithLetter.Length);
index += Math.Abs(TrigramsWithLetter.Length - letprop.TrigramsWithLetter.Length);*/
for (int i = 0; i <= 1; i++)
index += Math.Abs(BigramsWithLetter.Count(x => x[i] == Letter) - letprop.BigramsWithLetter.Count(x => x[i] == letprop.Letter));
for (int i = 0; i <= 2; i++)
index += Math.Abs(TrigramsWithLetter.Count(x => x[i] == Letter) - letprop.TrigramsWithLetter.Count(x => x[i] == letprop.Letter));
return index;
}
public LetterProperties(char letter, Dictionary ngrams, string ciphertext)
{
Letter = letter;
SplitedNgrams splitedNgrams = new SplitedNgrams(ngrams);
SymetricBigramsInTop = FindSymetricBigrams(letter, splitedNgrams.Top[2]);
BigramsWithLetter = FindNgramsWithLetter(letter, splitedNgrams.Top[2]);
TrigramsWithLetter = FindNgramsWithLetter(letter, splitedNgrams.Top[3]);
LettersBefore = NumbersBeforeLetter(letter, ciphertext);
LettersAfter = NumbersAfterLetter(letter, ciphertext);
}
private int NumbersBeforeLetter(char letter, string ciphertext)
{
List foundedLetters = new List();
for (int i = 1; i < ciphertext.Length; i++)
{
if (ciphertext[i] == letter)
if (!foundedLetters.Find(ciphertext[i - 1]))
foundedLetters.Add(ciphertext[i - 1]);
}
return foundedLetters.Count;
}
private int NumbersAfterLetter(char letter, string ciphertext)
{
List foundedLetters = new List();
for (int i = 0; i < ciphertext.Length - 1; i++)
{
if (ciphertext[i] == letter)
if (!foundedLetters.Find(ciphertext[i + 1]))
foundedLetters.Add(ciphertext[i + 1]);
}
return foundedLetters.Count;
}
///
/// Nalezne všechny ngramy, které obsahují dané písmeno
///
/// Písmeno, které se má vyskytovat v ngramu
/// Pole ngramů
/// Pole ngramů, které obsahují znak letter
private string[] FindNgramsWithLetter(char letter, string[] ngrams)
{
return ngrams.Where(x => x.Contains(letter)).ToArray();
}
///
/// Nalezne všechny symetrické ngramy. Tedy slova ve tvaru abc-cba
///
/// Písmeno, které musí být v ngramu obsaženo
/// Seznam ngramů, ve kterých se bude vyhledávat
/// Symetrické ngramy
private string[] FindSymetricBigrams(char letter, string[] ngrams)
{
List symetricBigrams = new List();
foreach (var bigram in ngrams)
if (bigram.Contains(letter) && ngrams.Find(bigram.Reverse()))
symetricBigrams.Add(bigram);
return symetricBigrams.ToArray();
}
}
}