コード例 #1
0
ファイル: Polyalph.cs プロジェクト: ComesToMind/Cryptograthy
        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;
            }
        }
コード例 #2
0
        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;
                    }
                }
            }
        }
コード例 #3
0
ファイル: Polyalph.cs プロジェクト: ComesToMind/Cryptograthy
 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;
     }
 }
コード例 #4
0
ファイル: Polyalph.cs プロジェクト: ComesToMind/Cryptograthy
        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 :;
            }
        }