В Древней Греции (2 век до н.э.) был известен шифр, называемый "Квадрат Полибия". Шифровальная таблица представляла собой квадрат с пятью столбцами и пятью строками, которые нумеровались цифрами от 1 до 5. В каждую клетку такого квадрата записывалась одна буква. В результате каждой букве соответствовала пара чисел, и шифрование сводилось к замене буквы парой чисел. Для латинского алфавита "Квадрат Полибия" имеет вид:
1 2 3 4 5
1 A B C D E
2 F G H J,I K
3 L M N O P
4 Q R S T U
5 V W X Y Z
И мне нужно было написать программу которая могла делать следующее:
а) Зашифровать введенный текст из консоли и сохранить его в текстовый файл;
б) Считает зашифрованный текст из файла и расшифрует данный текст выведя его на консоль.
Вообще "Квадрат Полибия" может иметь разный вид, но сегодня поговорим о создании программы с данной ранее таблице. Мы будем делать нашу программу в Visual Studio 2019, но для каких-нибудь 2020 и т.п. тоже подойдет.
!!!Все буквы будут обрабатываться исключительно капслоком в этой программе, т.е. если вы заполните массив буквами с маленькой буквы, то буквы с консоли будут обрабатываться исключительно с маленькой буквы!!!
И так, нам для работы нужны будут следующие библиотеки:
System;//основная
System.Collections.Generic;//основная
System.Linq;//основная
System.Text;//основная
System.Threading.Tasks;//основная
System.IO;//для записи и чтения файла
System.Threading;//основная
Для начала мы в классе создадим двумерный массив для букв из таблицы, строчку для чтения слов с консоли и три переменные, первая для дальнейшего соединения двух последних, вторая для указания пути к нужному файлу, а третья само наименование файла и его формат. В данном случае текстовый (txt).
Вот как это выглядит:
string[,] tableEng = new string[,] { { "A", "B", "C", "D","E" }, { "F", "G", "H", "I", "K" }, { "L", "M", "N", "O", "P" }, { "Q", "R", "S", "T", "U" }, { "V", "W", "X", "Y", "Z" }, }; string text; string filePath; string path = @"D:\\ТЫ ХОЧЕШЬ ЧТО ЛИ БАОБАБ НАЙТИ\\"; string file = @"\\память.txt";
Затем в классе мы объявляем публичный метод, где уже мы будем реализовать свой код. Я его назвала квадратом полибия, но только по английский, а вы можете назвать его по другому, но так чтобы каждый при одном его названии смог понять за что этот кусок кода отвечает.
Выводим на консоль инструкцию, а на следующей строке соединяем нужные нам переменные в одну для указания нужного файла.
Затем мы реализуем начало записи с консоли данных(букв) и в теле метода мы пишем следующее:
⦁ Объявляем цикл while для завершения ввода нужных слов, т.е. считываем данные с консоли до тех пор пока пользователь не введет * и не тыкнет ентер,
⦁ Считываем данные с клавиатуры,
⦁ С помощью Split разделяем слова на и записываем его в массив m,
C помощью Split мы можем с строки удалять пробелы, символы, знаки препинания, а также не нужные нам буквы. И это можно записать как показано ниже:
string[] words = line.Split(' ', ',', '.', '-', '=', '+', '!', '?', '^', '&');
⦁ С помощью foreach мы перебираем текст из массива,
⦁ А в следующем foreach мы перебираем текст уже с помощью переменной для символов, это нам понадобится для сравнения букв с буквами из массива tableEng,
⦁ Теперь мы перебираем с помощью циклов for массив tableEng, делаем цикл в цикле. Т.к. у нас массив двумерный, то нам нужно именно два цикла для перебора двух измерений в нем. А в сравнении, в циклах, где мы переменную i сравниваем с массивом, вместо Length мы будем использовать GetLength(), т.к. Length используется для одномерных массивов, а GetLength() для измерений многомерных массивов,
Length - для длины одномерных массивов
GetLength() - для длины измеренний многомерный массивов, в нашем случае двумерным. Если в скобочках напишем 0, то это будет длина первого измерения, если 1, то второго и т.д.
⦁ И пишем первое условие в if. Если в массиве какой-то из элементов массива tableEng равен символу из строки, то прибавляем к i + 1 и тоже самое к j + 1. Далее выводим все на консоль,
⦁ А внутри первого условия пишем второе для самого первого цикла while. Если переменная text равна *, то цикл прекращается, а данные с консоли записываются в файл.
Вот как выглядит код:
Console.WriteLine("Введите текст(только капслоком!!!!), который хотите зашифровать(для выхода * и ентер): "); filePath = Path.Combine("D:\\", path + file); //здесь зашифровываю текст по квадрату полибия и шифровку записываю в файл using (StreamWriter streamWriter = new StreamWriter(filePath, true, Encoding.UTF8)) //это страка для записи данных с консоли в файл { while (text != "*") { text = Console.ReadLine(); string[] m = text.Split(' '); foreach (string letter in m) { foreach (char c in letter) { for (int i = 0; i < tableEng.GetLength(0); i++) { for (int j = 0; j < tableEng.GetLength(1); j++) { if (tableEng[i, j] == c.ToString()) { int result = i + 1; int resu = j + 1; Console.WriteLine($"{i + 1}{j + 1} "); if (text == "*") break; streamWriter.Write($" {result}{resu} "); } } } } } } }
Далее мы реализуем начало чтения с файла данных(букв) и в теле мы пишем следующее:
⦁ Объявляем переменную для дальнейшего чтения строк из файла,
⦁ Объявляем цикл while, в котором мы считываем строки с файла до тех пор, пока они не будут равны нулю, т.е. пока не закончатся,
⦁ Далее мы объявляем массив words и в нем разделяем строки на отдельные слова и записываем в него,
⦁ В цикле foreach мы перебираем символы из массива words. И в этом цикле мы выводим данные из файла. А также мы символы из файла сравниваем с определенными символами с помощью оператора switch case и если есть совпадение, то вручную с помощью Console.WriteLine выводим определенный элемент из массива tableEng.
Вот как это будет выглядить:
using (StreamReader streamReader = new StreamReader(filePath)) { string line; while ((line = streamReader.ReadLine()) != null) { string[] words = line.Split(' '); foreach (var word in words) { Console.Write(word); switch (word) { case "11": Console.WriteLine($"{tableEng[0, 0]}"); break; case "12": Console.WriteLine($"{tableEng[0, 1]}"); break; case "13": Console.WriteLine($"{tableEng[0, 2]}"); break; case "14": Console.WriteLine($"{tableEng[0, 3]}"); break; case "15": Console.WriteLine($"{tableEng[0, 4]}"); break; case "21": Console.WriteLine($"{tableEng[1, 0]}");// break; case "22": Console.WriteLine($"{tableEng[1, 1]}"); break; case "23": Console.WriteLine($"{tableEng[1, 2]}"); break; case "24": Console.WriteLine($"{tableEng[1, 3]}"); break; case "25": Console.WriteLine($"{tableEng[1, 4]}"); break; case "31": Console.WriteLine($"{tableEng[2, 0]}"); break; case "32": Console.WriteLine($"{tableEng[2, 1]}"); break; case "33": Console.WriteLine($"{tableEng[2, 2]}"); break; case "34": Console.WriteLine($"{tableEng[2, 3]}"); break; case "35": Console.WriteLine($"{tableEng[2, 4]}"); break; case "41": Console.WriteLine($"{tableEng[3, 0]}"); break; case "42": Console.WriteLine($"{tableEng[3, 1]}"); break; case "43": Console.WriteLine($"{tableEng[3, 2]}"); break; case "44": Console.WriteLine($"{tableEng[3, 3]}"); break; case "45": Console.WriteLine($"{tableEng[3, 4]}"); break; case "51": Console.WriteLine($"{tableEng[4, 0]}"); break; case "52": Console.WriteLine($"{tableEng[4, 1]}"); break; case "53": Console.WriteLine($"{tableEng[4, 2]}"); break; case "54": Console.WriteLine($"{tableEng[4, 3]}"); break; case "55": Console.WriteLine($"{tableEng[4, 4]}"); break; } } } Console.ReadLine(); }
Если мы это делали в другой вкладке:
Далее в Main() мы объявляем класс, потом метод Cube_Polibiai() для вывода.
Вот так:
static void Main(string[] args) { Task_1 t = new Task_1(); t.Cube_Polibiai(); }
Вот так я писала эту программу :)
