Шифр Виженера – алгоритм шифрования текстовых данных с помощью ключевого слова.
Описание алгоритма
Шифрование Виженера можно представить как несколько шифров Цезаря с различными ключами. Проще всего шифры представить в виде таблицы, для английского алфавита мы получим 26 строк шифра Цезаря, в каждой строке сдвиг на единицу больше предыдущей:
Математически шифр Виженера можно описать следующими формулами:
- Encrypt(mn) = (Q + mn + kn) % Q;
- Decrypt(cn) = (Q + cn - kn) % Q.
где mn - позиция символа открытого текста, kn - позиция символа ключа шифрования, Q - количество символов в алфавите, cn - позиция символа зашифрованного текста.
Реализация шифрования Виженера
using System;
public class VigenereCipher
{
const string defaultAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
readonly string letters;
public VigenereCipher(string alphabet = null)
{
letters = string.IsNullOrEmpty(alphabet) ? defaultAlphabet : alphabet;
}
//генерация повторяющегося пароля
private string GetRepeatKey(string s, int n)
{
var p = s;
while (p.Length < n)
{
p += p;
}
return p.Substring(0, n);
}
private string Vigenere(string text, string password, bool encrypting = true)
{
var gamma = GetRepeatKey(password, text.Length);
var retValue = "";
var q = letters.Length;
for (int i = 0; i < text.Length; i++)
{
var letterIndex = letters.IndexOf(text[i]);
var codeIndex = letters.IndexOf(gamma[i]);
if (letterIndex < 0)
{
//если буква не найдена, добавляем её в исходном виде
retValue += text[i].ToString();
}
else
{
retValue += letters[(q + letterIndex + ((encrypting ? 1 : -1) * codeIndex)) % q].ToString();
}
}
return retValue;
}
//шифрование текста
public string Encrypt(string plainMessage, string password)
=> Vigenere(plainMessage, password);
//дешифрование текста
public string Decrypt(string encryptedMessage, string password)
=> Vigenere(encryptedMessage, password, false);
}
class Program
{
static void Main(string[] args)
{
//передаем в конструктор класса буквы русского алфавита
var cipher = new VigenereCipher("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ");
Console.Write("Введите текст: ");
var inputText = Console.ReadLine().ToUpper();
Console.Write("Введите ключ: ");
var password = Console.ReadLine().ToUpper();
var encryptedText = cipher.Encrypt(inputText, password);
Console.WriteLine("Зашифрованное сообщение: {0}", encryptedText);
Console.WriteLine("Расшифрованное сообщение: {0}", cipher.Decrypt(encryptedText, password));
Console.ReadLine();
}
}
Результат работы программы: