вентилятор
Хорошего настроения!

Шифр Виженера на C#



Здравствуйте, дорогие читатели блога Code-Enjoy.ru! До конца сентября хотелось написать ещё какую-нибудь жирную статью. И конечно же на языке программирования C#!


Сегодня продолжим изучать алгоритмы шифрования данных. И самый простой, примитивный алгоритм - это шифр Цезаря, который я уже рассматривал на страницах своего сайта. Пусть нам нужно зашифровать какое-нибудь текстовое сообщение. Суть метода Цезаря заключается в том, что мы каждой букве назначаем другую букву из алфавита. Например букве "а" -> "г", букве "б"-> "д" и т.д. Соответствие букв идёт по кольцу, т.е. букве "э" будет соответствовать буква "а".


Таким образом, слово "привет" будет закодировано в "тулезх". Сдвиг букв может быть на любое количество символов. Но данный способ является очень не надёжным. На этом, как известно, и погорел Цезарь!


Во-первых можно перебрать все 32 варианта, чтобы узнать на какое количество символов смещены символы. Во-вторых, известно, что буква "о" встречается чаще, чем другие буквы (9.28%). Из этого следует, что если мы имеем достаточный объем зашифрованного текста, мы можем вычислить часто встречающиеся символы, а затем вычислить остальные.


Более надёжным алгоритмом является шифр Виженера. Идея его заключается в том, что мы даже одной и той же букве можем поставить в соответствие разные буквы. Величина смещения каждой буквы в конкретной позиции определяется с помощью ключа.





Шифр Виженера на C#


В данном случае мы шифруем строку "тестовая строка" с помощью ключа "книга". Первая идёт буква "т" под ней находится буква ключа "к". Буква "к" имеет номер 11 в алфавите, если считать с нуля. Значит, мы должны сместить букву "т" на 11 позиций. Затем берём следующую букву "е". Под ней находится буква ключа "н". Буква "н" имеет номер 14. Значит мы должны сместить букву "е" на 14 позиций в алфавите по кольцу и т.д. Ключ повторяется сколько раз, сколько нужно и записывается под сообщением.


Таким образом, шифр Виженера является более защищённым, чем шифр Цезаря, за счет того, что мы всегда смещаем буквы на разное количество символов.


Задача: Написать программу, которая считывает сообщение из файла 1.txt, шифрует это сообщение шифром Виженера (ключ считывается из файла 2.txt) и записывает результат в файл 3.txt. Задачу применить только к буквам русского алфавита нижнего регистра. Если встретятся символы не из русского алфавита, то их оставить без изменений.



Решение: Напишем программу на языке C# (Си шарп).


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ConsoleApp8
{
    class Program
    {
        static void Main(string[] args)
        {
            // Cчитываем из файла сообщения
            string m = File.ReadAllText("1.txt", Encoding.GetEncoding(1251));
            string k = File.ReadAllText("2.txt", Encoding.GetEncoding(1251));

            int nomer; // Номер в алфавите
            int d; // Смещение
            string s; //Результат
            int j,f; // Переменная для циклов
            int t=0; // Преременная для нумерации символов ключа.

            char[] massage = m.ToCharArray(); // Превращаем сообщение в массив символов.
            char[] key = k.ToCharArray(); // Превращаем ключ в массив символов.

            char[] alfavit = { 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я'};

            // Перебираем каждый символ сообщения
            for (int i = 0; i < massage.Length; i++)
            {
                // Ищем индекс буквы
                for (j = 0; j < alfavit.Length; j++)
                {
                    if (massage[i] == alfavit[j])
                    {
                        break;
                    }
                }

                if (j != 33) // Если j равно 33, значит символ не из алфавита
                {
                    nomer = j; // Индекс буквы

                    // Ключ закончился - начинаем сначала.
                    if ( t > key.Length - 1) { t = 0; } 

                    // Ищем индекс буквы ключа
                    for (f = 0; f < alfavit.Length; f++)
                    {
                        if (key[t] == alfavit[f])
                        {
                            break;
                        }
                    }

                    t++;

                    if (f != 33) // Если f равно 33, значит символ не из алфавита
                    {
                        d = nomer + f;
                    }
                    else
                    {
                        d = nomer;
                    }
                
                    // Проверяем, чтобы не вышли за пределы алфавита
                    if (d > 32)
                    {
                        d = d - 33;
                    }

                    massage[i] = alfavit[d]; // Меняем букву
                }
            }

            s = new string(massage); // Собираем символы обратно в строку.
            File.WriteAllText("3.txt", s); // Записываем результат в файл.

        }

    }
}

В файле 1.txt было сообщение:
привет это тестовая строка

Ключ в файле 2.txt:
программирование

Результат в файле 3.txt:
ябчехт йяч гуутькео вбуякм

Счастливого программирования!





25-09-2018 в 20:26:22





Поддержать сайт:


Похожая статья:

Шифр Цезаря на C#

Сегодня разберём самой простой тип шифрования текста - шифр Цезаря....

Категория: Алгоритмы  Подкатегория: Шифрование
Дата: 11-01-2018 в 20:31:51 0


Комментарии:

а можно расшифровку?
артем 16-10-2019 в 15:46:48

Можете мне заказать.
Калужский Александр 03-12-2019 в 17:04:01

зачем перебирать в цикле массив, чтобы найти букву - есть же прекрасный метод Contains(тут_ваш_элемент)
Dmeetrogon 23-07-2023 в 12:33:37

Код немного не эффективен, тут достаточно LINQ. На малых примерах конечно заметно не будет, но при работе с реальными массивами - разница в скорости будет на порядки выше
Рукалицо 03-09-2023 в 12:03:57



Оставить коментарий:



Напишите email, чтобы получать сообщения о новых комментариях (необязательно):


Задача против робота. Расположите картинки горизонтально:




Нажимая кнопку Отправить, Вы соглашаетесь с политикой конфиденциальности сайта.