Шифр Плейфера - C#
Формулировка задачи:
Здравствуйте, для начала расскажу что за шифр такой: Для начала берется матрица и в первую очередь в нее вписывается ключевое слово(без повторяющихся символов), потом заполняют оставшиеся ячейки матрицы символами алфавита, не встречающимися в ключевом слове, по порядку. Затем буквы исходного текста разбиваются на биграммы(2 символа), в случае если количество символов в исходном тексте нечетное - в конец исходного текста добавляется символ «Я». Руководствуясь следующими 4 правилами зашифровываем пары символов исходного текста:
1. Если два символа биграммы совпадают, добавляем после первого символа «Я», зашифровываем новую пару символов и продолжаем.
2. Если символы биграммы исходного текста встречаются в одной строке, то шифрограмма получается путём сдвига вправо на 1 клетку. Если символ является последним в строке, то он заменяется на первый символ этой же строки.
3. Если символы биграммы исходного текста встречаются в одном столбце, то они преобразуются в символы того же столбца, находящимися непосредственно под ними. Если символ является нижним в столбце, то он заменяется на первый символ этого же столбца.
4. Если символы биграммы исходного текста находятся в разных столбцах и разных строках, то они заменяются на символы, находящиеся в тех же строках, но соответствующие другим углам прямоугольника.
Программа практически готова, казалось бы живи да радуйся, но нет. В случае если в одной биграмме буквы одинаковые программа просто добавляет после первой буквы биграммы "Я", а одинаковые буквы биграммы шифрует по 3 правилу. Пример: исходный текст "КОЛЛЕДЖ". Шифруем по следующей таблице:
Программа зашифрует текст как ИРСЯСАЕЗЮ. А нужно чтобы чтобы зашифровало так: КО=ИР , ЛЯ=З! , ЛЕ=СЛ , ДЖ=АК. Зашифрованный текст: ИРЗ!СЛАК.
Мозг кипит и потому прошу помощи у Вас.
Код программы:
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я _ , . !
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { char[] alphabet = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ ,.!".ToCharArray(); string text; //исходный текст для шифрования int i_first = 0, j_first = 0; //координаты первого символа пары int i_second = 0, j_second = 0;//координаты второго символа пары string s1 = "", s2 = ""; //строки для хранения зашифрованного символа string encodetString; //зашифрованая строка int rows = 0, columns = 0; int i, j; text = ""; encodetString = ""; bool isValidTable; do { Console.Write("Количество колонок в таблице: "); isValidTable = int.TryParse(Console.ReadLine(), out columns) && columns > 1; //переменной isValidTable присваиваем преобразованное целое число(количество стобцов) в качестве аргумента if (!isValidTable) { Console.WriteLine("Необходимо ввести число больше 1"); } else { rows = alphabet.Length / columns; isValidTable &= rows > 1 && rows * columns == alphabet.Length; if (!isValidTable) { Console.WriteLine("Необходимо ввести число колонок таким образом, чтобы число строк таблицы было больше 1 и таблица могла вмещать в себе все символы алфавита"); } } } while (!isValidTable); //выполнять пока false // Пытаемся получить ключевое слово char[] keyWord; bool isValidKeyWord; do { Console.Write("Введите ключевое слово: "); keyWord = Console.ReadLine().ToUpper().Distinct().ToArray(); // Преобразуем в строковое представление, считываем ключ, переводим в верхний регистр, удаляем повторения, преобразуем в массив. isValidKeyWord = keyWord.Length > 0 && keyWord.Length <= alphabet.Length; // если длина ключa > 0 и <= длины алфавита то возвращаем true/иначе false if (!isValidKeyWord) // если false { Console.WriteLine("Ключевое слово не может быть пустой строкой или содержать число уникальных символов больше размера алфавита"); } else { isValidKeyWord = !keyWord.Except(alphabet).Any(); //возвратит true, если ключ не содержит элементов, не имющихся в алфавите/иначе false if (!isValidKeyWord) //если false { Console.WriteLine("Ключевое слово не может содержать символы, которых нет в алфавите"); } } } while (!isValidKeyWord); //выполнять пока false // Создаем таблицу var table = new char[rows, columns]; // Вписываем в нее ключевое слово for (i = 0; i < keyWord.Length; i++) { table[i / columns, i % columns] = keyWord[i]; } // Исключаем уникальные символы ключевого слова из алфавита alphabet = alphabet.Except(keyWord).ToArray(); // Вписываем алфавит for (i = 0; i < alphabet.Length; i++) { int position = i + keyWord.Length; table[position / columns, position % columns] = alphabet[i]; } for (i = 0; i < rows; i++) { for (j = 0; j < columns; j++) { Console.Write(table[i, j]+" "); } Console.WriteLine(); } Console.WriteLine("Введите текст для зашифровки:"); text = Console.ReadLine().ToUpper(); int t = text.Length; //длина входного слова ///проверяем, четное ли число символов в строке int temp = t % 2; if (temp != 0) //если нет { //то добавляем в конец строки символ " " text = text.PadRight((t + 1), 'Я'); } int len = text.Length / 2; /*длина нового массива - равная половине длины входного слова т.к. в новом масиве каждый элемент будет содержать 2 элемента из старого массива*/ string[] str = new string[len]; //новый массив int l = -1; //служебная переменная for (i = 0; i < t; i += 2) //в старом массиве шаг равен 2 { l++; //индексы для нового массива if (l < len) { //Элемент_нового_массива[i] = Элемент_старого_массива[i] + Элемент_старого_массива[i+1] str[l] = Convert.ToString(text[i]) + Convert.ToString(text[i + 1]); } } ///координаты очередного найденного символа из каждой пары foreach (string both in str) { for (i = 0; i < rows; i++) { for (j = 0; j < columns; j++) { //координаты первого символа пары в исходной матрице if (both[0] == (table[i, j])) { i_first = i; j_first = j; } //координаты второго символа пары в исходной матрице if (both[1] == (table[i, j])) { i_second = i; j_second = j; } } } ///если пара символов находится в одной строке if (i_first == i_second) { if (j_first == columns-1) /*если символ последний в строке, кодируем его первым символом из матрицы*/ { s1 = Convert.ToString(table[i_first, 0]); } //если символ не последний, кодируем его стоящим справа от него else { s1 = Convert.ToString(table[i_first, j_first + 1]); } if (j_second == columns-1) /*если символ последний в строке кодируем его первым символом из матрицы*/ { s2 = Convert.ToString(table[i_second, 0]); } //если символ не последний, кодируем его стоящим справа от него else { s2 = Convert.ToString(table[i_second, j_second + 1]); } } ///если пара символов находится в одном столбце if (j_first == j_second) { if (i_first == rows-1) { s1 = Convert.ToString(table[0, j_first]); } else { s1 = Convert.ToString(table[i_first + 1, j_first]); } if (i_second == rows-1) { s2 = Convert.ToString(table[0, j_second]); } else { s2 = Convert.ToString(table[i_second + 1, j_second]); } } ///если пара символов находиться в разных столбцах и строках if (i_first != i_second && j_first != j_second) { s1 = Convert.ToString(table[i_first, j_second]); s2 = Convert.ToString(table[i_second, j_first]); } if (s1 == s2) { encodetString = encodetString + s1 + "я" + s2; } else { //записыавем результат кодирования encodetString = encodetString + s1 + s2; } Console.WriteLine(encodetString.ToLower()); } Console.ReadKey(); } } }
Решение задачи: «Шифр Плейфера»
textual
Листинг программы
namespace cnsle { public class Program { private static void ActivateMenu() { ... } public static T ReadValueFromConsole<T>(string message) { ... } static void Main(string[] args) { ... } } public class PlayfairCipher { ... } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д