private void fieldKey_KeyPress(object sender, KeyPressEventArgs e) { char symb = e.KeyChar; if (fieldCiphertext.TextLength > 0 && (alphabet.IndexOf(symb) == -1 && ALPHABET.IndexOf(symb) == -1 && symb != (char)8)) { e.Handled = true; } }
public static void Run() { var boxIds = File.ReadAllLines(@"Day2\Input.txt"); const string ALPHABET = "abcdefghijklmnopqrstuvwxyz"; int boxesWithLetterTwice = 0; int boxesWithLetterThrice = 0; foreach (var boxId in boxIds) { if (ALPHABET.Any(x => boxId.Count(c => c == x) == 2)) { boxesWithLetterTwice += 1; } if (ALPHABET.Any(x => boxId.Count(c => c == x) == 3)) { boxesWithLetterThrice += 1; } } Console.WriteLine($"Part 1: {boxesWithLetterTwice * boxesWithLetterThrice}"); foreach (var box1 in boxIds) { foreach (var box2 in boxIds) { if (box1 == box2) { continue; } var resultBuilder = new StringBuilder(); for (int i = 0; i < box1.Length; i++) { if (box1[i] == box2[i]) { resultBuilder.Append(box1[i]); } } var result = resultBuilder.ToString(); if (result.Length + 1 == box1.Length) { Console.WriteLine($"Part 2: {result}"); return; } } } }
private void fieldKey_TextChanged(object sender, EventArgs e) { //РАСШИФРОВАНИЕ ПО ВВЕДЕННОМУ КЛЮЧУ if (fieldKey.TextLength > 0) { string res = ""; int j = 0; for (int i = 0; i < fieldCiphertext.TextLength; i++) { int curSymbNum = alphabet.IndexOf(fieldCiphertext.Text[i]); int rotSymbNum = alphabet.IndexOf(fieldKey.Text[j]); if (curSymbNum != -1) {//строчная буква res += alphabet[((curSymbNum - rotSymbNum) + alphabet.Length) % alphabet.Length]; j++; j = j % fieldKey.TextLength; } else { curSymbNum = ALPHABET.IndexOf(fieldCiphertext.Text[i]); if (curSymbNum != -1)//заглавная буква { res += ALPHABET[((curSymbNum - rotSymbNum) + ALPHABET.Length) % ALPHABET.Length]; j++; j = j % fieldKey.TextLength; } else { //Символы, которых нет в алфавите, просто res += fieldCiphertext.Text[i]; } } } fieldOriginal.Text = res; } else { fieldOriginal.Text = null; } }
private void buttonFindKeyLength_Click(object sender, EventArgs e) { //МЕТОДЫ поиска длины ключа keyLengthUpDown.Value = 0; //Сброс комбобокса if (MatchIndex_radioButton.Checked && fieldCiphertext.TextLength > 0) { //метод индекса совпадений int possibleLen = 1; while (possibleLen < fieldCiphertext.Text.Length) { string Source = fieldCiphertext.Text.ToLower(); string everyXdiv = ""; // Формируем строку БЕЗ УЧЕТА РАЗДЕЛИТЕЛЕЙ //каждый символ текста через длинну ключа шифруется одним и тем же смиволом ключа int j = 0; for (int i = 0; i < Source.Length; i++) { if (j % possibleLen == 0 && (alphabet.IndexOf(Source[i]) != -1 || ALPHABET.IndexOf(Source[i]) != -1)) { everyXdiv += Source[i]; j++; } else if (j % possibleLen != 0 && (alphabet.IndexOf(Source[i]) != -1 || ALPHABET.IndexOf(Source[i]) != -1)) { j++; } } //Подсчитаем индекс double index = 0; int[] times = new int[alphabet.Length]; //Array.Clear(times, 0, alphabet.Length); //Вычислим количество вхождений каждой буквы int amount = 0; for (int i = 0; i < everyXdiv.Length; i++) { if (alphabet.IndexOf(everyXdiv[i]) >= 0) { amount++; times[alphabet.IndexOf(everyXdiv[i])]++; } } //теперь по формуле общего случая индекса совпадений f_i(f_i-1)/n(n-1) for (int i = 0; i < times.Length; i++) { index += (times[i]) * (times[i] - 1); } index = index / (double)(amount * (amount - 1)); //if ((index > 0.0553 && alph_check_ru) || (index > 0.0644 && alph_check_en)) if (index > 0.0553) { keyLengthUpDown.Value = possibleLen; goto m_exit; } possibleLen++; } m_exit :; } if (Autocorr_radioButton.Checked && fieldCiphertext.TextLength > 0) { //АВТОКОРЕЛЯЦИОННЫЙ МЕТОД string Source = (fieldCiphertext.Text).ToLower(); for (int i = 0; i < Source.Length; i++) //Удаляем разделители { if (alphabet.IndexOf(Source[i]) < 0) { string tmpDel = ""; tmpDel += Source[i]; Source = Source.Replace(tmpDel, ""); } } for (int possibleLength = 1; possibleLength < fieldCiphertext.Text.Length; possibleLength++) { //циклический сдвиг строки string copySource = Source.Substring(possibleLength) + Source.Substring(0, possibleLength); int coincidences = 0; //количество совпадений букв for (int i = 0; i < Source.Length; i++) { if (Source[i] == copySource[i]) { coincidences++; } } //А так как индекс совпадений вводится как вероятность совпадения двух произвольных букв в строке, // то для сдвигов, кратных или равных периоду, автокорреляционные коэффициенты, // при достаточно большой длине текста, будут близки к индексу совпадений естественного языка double index = coincidences / (double)Source.Length; //if ((index > 0.0553 && alph_check_ru) || (index >0.0644 && alph_check_en )) if (index > 0.0553) { keyLengthUpDown.Value = possibleLength; break; } } } if (Casiski_radioButton.Checked && fieldCiphertext.TextLength > 0) { string Source = (fieldCiphertext.Text).ToLower(); for (int i = 0; i < Source.Length; i++) //Удаляем разделители { if (alphabet.IndexOf(Source[i]) < 0) { string tmpDel = ""; tmpDel += Source[i]; Source = Source.Replace(tmpDel, ""); } } if (Source.Length < 10) { MessageBox.Show("Недостаточная длина текста для метода Касиски!", "Внимание!"); goto m_exit; } string checked_sublines = ""; //В эту строку через пробел далее записывать проверенные строки List <int> possibleLengths = new List <int>(); //если индекс в ней -1 то можно проверять, иначе - не надо for (int i = 0; i < Source.Length / 3 - 1; i++) { string subline = Source.Substring(i, 3); if (checked_sublines.IndexOf(subline) == -1) { //Считаем количество вхождений подстроки int times = 0; int j = 0; while (Source.IndexOf(subline, j) != -1) { j = Source.IndexOf(subline, j) + 1; //Следующий поиск начнем после текущего вхождения times++; } ; if (times >= 3) { checked_sublines += subline + " "; List <int> positionsDifference = new List <int>(); int prev = Source.IndexOf(subline); //первое вхождение j = prev + 1; //начнем поиск со второго while (Source.IndexOf(subline, j) != -1) { int curIndex = Source.IndexOf(subline, j); positionsDifference.Add(curIndex - 1); prev = curIndex; j = curIndex + 1; } ; int curGCD = positionsDifference[0]; for (int k = 1; k < positionsDifference.Count; k++) { curGCD = GCD(curGCD, positionsDifference[k]); } if (curGCD > 1) { possibleLengths.Add(curGCD); } } } } if (possibleLengths.Count > 0) { possibleLengths.Sort(); int[] possibility = new int[50]; int i = 0; while (i < possibleLengths.Count() && possibleLengths[i] < 50) { possibility[possibleLengths[i]]++; i++; } for (i = 0; i < 50; i++) { possibility[i] = possibility[i] * i; //Уменьшим значимость ложных срабатываний } for (i = 0; i < 50; i++) { if (possibility[i] == possibility.Max()) { keyLengthUpDown.Value = i; } } } m_exit :; } }