В Древней Греции (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();
}
Вот так я писала эту программу :)