Шифр Віженера – алгоритм шифрування текстових даних за допомогою ключового слова.
Опис алгоритму
Шифрування Віженера можна уявити як декілька шифрів Цезаря з різними ключами. Найпростіше шифри представити у вигляді таблиці, для англійського алфавіту ми отримаємо 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();
}
}
Результат роботи програми: