Шифр Виженера (Реализация на С++)

C++   6 июня 2012  Автор статьи:  

Программа выполняет шифрование алгоритмом Виженера. При этом шифруются только символы алфавита латиницы, остальные остаются без изменения.
Реализация данного алгоритма на C++:

//Программа шифрования/дешифрования символов латиницы алгоритмом Виженера
#include
#include
#include
#include
#include
#include

using namespace std;
int main()
{
int k; //Переменная выбора - шифрование/дешифрование
string result = ""; //Строка - результат
string key = ""; //Строка - ключ
string key_on_s = "";
bool flag;
int x = 0, y = 0; //Координаты нового символа из таблицы Виженера
int registr = 0; //Регистр символа
char dublicat; //Дубликат прописной буквы
//Формирование таблицы Виженера на алфавите латиницы
int shift = 0;
char **tabula_recta = new char *[26]; //Таблица Виженера
for (int i=0;i<26;i++) tabula_recta[i] = new char [26]; string alfabet = "abcdefghijklmnopqrstuvwxyz"; //Алфавит латиницы //Формирование таблицы for (int i = 0; i < 26; i++) for (int j = 0; j < 26; j++) { shift = j + i; if (shift >= 26) shift = shift % 26;
tabula_recta[i][j] = alfabet[shift];
}
cout<<"Enter 1 for encryption and decryption of 2\n"; cin>>k;
switch (k) //Если k
{
case 1: //Если выбрано шифрование
{
cout<<"Enter key encryption\n"; cin>>key;
cout<<"Read of file...\n"; setlocale(LC_ALL,"Russian");//Чтение файла string s; //Строка считанная из файла ifstream in("Test.txt"); getline(in,s); cout<<"Text of file: \n"< 122))
result += s[i];
else
{
//Поиск в первом столбце строки, начинающейся с символа ключа
int l = 0;
flag = false;
//Пока не найден символ
while ((l < 26) && (flag == false)) { //Если символ найден if (key_on_s[i] == tabula_recta[l][0]) { //Запоминаем в х номер строки x = l; flag = true; } l++; } //Уменьшаем временно регистр прописной буквы if (((int)(s[i]) <= 90) && ((int)(s[i]) >= 65))
{
dublicat = (char)((int)(s[i]) + 32);
registr = 1;
}
else
{
registr = 0;
dublicat = s[i];
}
l = 0;
flag = false;
//Пока не найден столбец в первой строке с символом строки
while ((l < 26) && (flag == false)) { if (dublicat == tabula_recta[0][l]) { //Запоминаем номер столбца y = l; flag = true; } l++; } //Увеличиваем регистр буквы до прописной if (registr == 1) { //Изменяем символ на первоначальный регистр dublicat = char((int)(tabula_recta[x][y]) - 32); result += dublicat; } else result += tabula_recta[x][y]; } } cout<<"Encryption complete!\n"; cout<<"Result:\n"; cout<>key;
cout<<"Read of file...\n"; setlocale(LC_ALL,"Russian"); string s; ifstream in("Test.txt"); getline(in,s); cout<<"Text of file: \n"< 122))
result += s[i];
else
{
//Поиск в первом столбце строки, начинающейся с символа ключа
int l = 0;
flag = false;
//Пока не найден символ
while ((l < 26) && (flag == false)) { //Если символ найден if (key_on_s[i] == tabula_recta[l][0]) { //Запоминаем в х номер строки x = l; flag = true; } l++; } //Уменьшаем временно регистр прописной буквы if (((int)(s[i]) <= 90) && ((int)(s[i]) >= 65))
{
dublicat = (char)((int)(s[i]) + 32);
registr = 1;
}
else
{
registr = 0;
dublicat = s[i];
}
l = 0;
flag = false;
//Пока не найден столбец в x строке с символом строки
while ((l < 26) && (flag == false)) { if (dublicat == tabula_recta[x][l]) { //Запоминаем номер столбца y = l; flag = true; } l++; } //Увеличиваем регистр буквы до прописной if (registr == 1) { //Изменяем символ на первоначальный регистр dublicat = char((int)(tabula_recta[0][y]) - 32); result += dublicat; } else result += tabula_recta[0][y]; } } cout<<"Decryption complete!\n"; cout<<"Result:\n"; cout<

  • Алекс

    всё работает, вот только вопрос ввожу ключ, а он должен читать все из файла, какой именно файл нужно создать?

    • Test.txt, но в коде можно изменить на любой другой.

      • Виталий

        Вопрос, а где указывается путь к файлу test.txt? не могу сообразить

        • Строка 45, ifstream — это тип данных потока. Работа с ним происходит в принципе также как с любым потоком. Он создается от какого-то файла или чего-то другого(например, соединения). Если вы создаете поток к файлу, то обычно указываете путь к нему. Путь можно указать как относительный, как в строчке 45, так и абсолютный (C://Text.txt) В случае относительного пути он будет считаться от директории кода. (Debug в случае компиляции в Degug режиме). Ну и так далее. Можно руками прям в дебаг добавить, но тру кодеры так не делают. Обычно прям в вижаке в проект добавляют нужные текстовые файлы(их можно добавить также как любые другие файлы) В общем ifstream мало чем отличается от freopen. Ну про фриопен я писал http://cybern.ru/faleinoutincpp.html

  • r04

    чето говнокод какой-то. Написал на коленке, вроде бы красивей (не проверял, МБ баги где-то?)

    #include
    #include
    #include
    #include
    int main(){
    std::string
    alf = «abcdefghijklmnopqrstuvwxyz»,
    key = «key»;
    std::ifstream ifst;
    std::ofstream ofst;
    int keylen = key.length();
    int alflen = alf.length();
    // шифрование
    ifst.open(«in.txt»);
    ofst.open(«code.txt»);
    for (int i = 0;; ++i) {
    i %= keylen;
    char c = ifst.get();
    if (ifst.eof())
    break;
    if (alf.end() == std::find(alf.begin(), alf.end(), c)) {
    ofst << c;
    continue;
    }
    ofst << alf[(c — 2 * alf[0] + key[i]) % alflen];
    }
    ofst.close();
    ifst.close();
    // расшифрование
    ifst.open("code.txt");
    ofst.open("decode.txt");
    for (int i = 0;; ++i) {
    i %= keylen;
    char c = ifst.get();
    if (ifst.eof())
    break;
    if (alf.end() == std::find(alf.begin(), alf.end(), c)) {
    ofst << c;
    continue;
    }
    ofst << alf[(c + alflen — key[i]) % alflen];
    }
    ofst.close();
    ofst.close();
    }

    Тут исходный файл шифруется, потом расшифровывается (содержимое исходного и расшифрованного файла можно сравнить).

    ЗЫ. подсветка кода яростно глючит (что-то вставляет закрывающие теги для и прочих) — этож беспридел. И еще у меня в комментариях почему то пустые строки дублируются (в коде тоже) — это бесит xD

    PS. я предлагаю однажды обменяца ссылками, что думаешь по этому поводу?

    • r04

      А вот еще вариант(нужен компилятор с поддержкой с++11):

      #include
      #include
      #include
      #include
      using namespace std;
      template
      void f(string iname, string oname, string &alf, string &key, Fun fun) {
      ifstream ifst(iname);
      ofstream ofst(oname);
      int keylen = key.length();
      for (int i = 0;; ++i) {
      i %= keylen;
      char c = ifst.get();
      if (ifst.eof()) break;
      if (alf.end() == find(alf.begin(), alf.end(), c))
      ofst << c;
      else
      ofst << fun(key, alf, c, i);
      }
      ofst.close();
      ifst.close();
      }
      int main(){
      string
      alf = "abcdefghijklmnopqrstuvwxyz",
      key = "key";
      // шифрование
      f("in.txt", "code.txt", alf, key, [](string key, string alf, char c, int i) {
      return alf[(c — 2 * alf[0] + key[i]) % alf.length()];
      });
      // расшифрование
      f("code.txt", "decode.txt", alf, key, [](string key, string alf, char c, int i) {
      return alf[(c + alf.length() — key[i]) % alf.length()];
      });
      }

      PS. тут твой подсветчик синтаксиса ваще код изгадил )) (я про шаблон сейчас)

      • На счет сотрудничества пишите на почту lordrp@bk.ru. У меня есть встречные предложения.

    • Подсветка кода в комментариях в комментариях обеспечивается disqus, а не WP, поэтому она не работает. На счет обмена ссылками, я до сих пор не знаю, как это правильно делать, так как не посмотрел пару докладов. Ну это там новые тенденции в SEO и вот там на конференции TOPExpert вроде их как спалили, а я так и не посмотрел.

Научиться программировать

  • на Delphi

  • на Java

  • на C++