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

Количество просмотров: 3696

Описание

Система Виженера впервые была опубликована в 1586 г. и является одной из старейших и наиболее известных многоалфавитных систем. Свое название она получила по имени французского дипломата XVI века Блеза Виженера, который развивал и совершенствовал криптографические системы.

Система Виженера подобна такой системе шифрования Цезаря, у которой ключ подстановки меняется от буквы к букве. Этот Шифр многоалфавитной замены можно описать таблицей шифрования, называемой таблицей (квадратом) Виженера. Каждая строка таблицы представляет собой символы используемого алфавита с циклическим сдвигом на n позиций.

Таблица Виженера для английского алфавита

Таблица Виженера для русского алфавита

Таблица Виженера используется для зашифрования и расшифрования. Таблица имеет два входа:

  • верхнюю строку подчеркнутых символов, используемую для считывания очередной буквы исходного открытого текста;
  • крайний левый столбец ключа.

Последовательность ключей обычно получают из числовых значений букв ключевого слова.

При шифровании исходного сообщения его выписывают в строку, а под ним записывают ключевое слово (или фразу). Если ключ оказался короче сообщения, то его циклически повторяют. В процессе шифрования находят в верхней строке таблицы очередную букву исходного текста и в левом столбце очередное значение ключа. Очередная буква шифртекста находится на пересечении столбца, определяемого шифруемой буквой, и строки, определяемой числовым значением ключа.

Реализация

Исходники

Для начала подключим требуемые библиотеки

#include "stdafx.h"
#include <iostream>
#include <string>
#include <conio.h>
#include "locale.h"
#include <fstream>

и объявим необходимые переменные

	setlocale(LC_ALL,"Russian");//русская локаль
	int i,j,index, index_key, index_message, number;
	// find_key - флажок найденного индекса строки
	// find_message - - флажок найденного индекса столбца
	int find_key=0, find_message=0, count_a, count_b, success=0;
	//строка исходного текста
	string message;
	//Строка - ключ 
	string key = "asd"; 
	// строка, образованная повтором ключа
    string repeat_key = "";
	// строка алфавита
	string alpha="abcdefghijklmnopqrstuvwxyz";
	// таблица виженера
	char table[26][26];

Заполняем таблицу Виженера. Складывая номера строки и столбца ячейки таблицы, мы получаем индекс элемента в массиве, хранящем символы алфавита. Значение элемента массива копируем в текущую ячейку.

for(i=0; i<26; i++)
		for(j=0;j<26;j++)
		{
			index=i+j;
			if(index>=26) index=index%26;
				table[i][j]=alpha[index];
		}

Считываем из текстового файла исходную фразу. Далее циклически повторяем ключ.

				repeat_key="";
				message="";
				ifstream file("C:\\input.txt");
				while(file)
				{
					file>>message;
				}
				cout<<message<<endl;
				for (i = 0; i < message.length(); i++)
				{
					repeat_key += key[i % key.length()];
				}

Для расшифровки находим символ на пересечении столбца с символом из текста и строки с символом из ключа.

for(i=0; i<message.length(); i++)
{
    count_a=0;
    while(count_a<26 && (find_key==0))
    {
        if(repeat_key[i]==table[0][count_a])
	{
	    index_key=count_a;
	    find_key=1;
	}
	count_a++;
    }
    find_key=0;
    count_b=0;
    while(count_b<26 && (find_message==0))
    {
        if(message[i]==table[count_b][0])
	{
	    index_message=count_b;
	    find_message=1;
	}
        count_b++;
    }
    find_message=0;
    cout<<table[index_message][index_key];				
}

Дешифровка

repeat_key="";
				message="";
				ifstream file1("C:\\output.txt");
				while(file1)
				{
					file1&rt;&rt;message;
				}
				file1.close();
						// составим строку из повторов ключа длиной равной длине сообщения
				for (i = 0; i < message.length(); i++)
				{
					repeat_key += key[i % key.length()];
				}
				for(i=0; i<message.length(); i++)
				{
					count_a=0;
					count_b=0;
					while(count_a<26 && (find_key==0))
					{
						if(repeat_key[i]==table[count_a][0])
						{
							index_key=count_a;
							find_key=1;
						}
						count_a++;
					}
					find_key=0;
					while(count_b<26 && (find_message==0))
					{
						if(message[i]==table[index_key][count_b])
						{
							index_message=count_b;
							find_message=1;
						}
						count_b++;
					}
					find_message=0;
					cout<<table[0][index_message];
				}		
				cout<<endl;
			}
			break;

comments powered by HyperComments

© 2015-2018 Goodweb.me --- Карта сайта --- info@goodweb.me

Наверх