24.11.2016, 19:24
общий
это ответ
Здравствуйте, dteplyakova80!
Подправил код. Сравните.
Замечания:
1) По шифру Плейфера требуется вставлять между двумя одинаковыми символами,
как и в конце для дополнения до четного числа символов, какой-то другой. Я взял 'X'.
После дешифровки данный символ (смотреть по смыслу) удалять
2) Для создания решетки надо использовать принятые правила.
(Английских букв 26*2 = 52, а надо 25*2 = 50).
Принято выкидать или буквы J,j или Q,q. Я заменяю J,j на I,i
У Вас же было, что буковки y,z - пропали. Что будет, если они будут в строке? (заменятся на A, как не найденные)
3) В конце был мусор, потому что надо строку завершать нулем.
4) Строки оригинально задавали.
char MyText[] = "";
Здесь задается указатель на пустую строку. Запись в строку по указателю большему 0 неминуемо приведет к затиранию чего-то другого!
5) Строковые операции с суффиксом _s требуют указания длины приемного буфера, как раз, для предотвращения переполнения буфера!
[code h=200]
/*
Данный алгоритм реализует шифр Плейфера,
но у меня возникли две проблемы:
1) при дешифровке программа приписывает рандомный символ в конце
(я думаю что моя реализация шифрования шифрует нулевой символ
массива введённого текста)
2) если я реализую ввод текста через scanf("%s",&MyText);
тогда компилятор выдаёт мне ошибку
"error C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead"
как я понял,что просит установить scanf_s,но если я его установлю
то при выборе пункта "Ввод текста" в меню программы он просто его пропускает,
а также хотелось бы вводить строку чтобы кодировалась строка
но также реализуя ввод через cin.getline(MyText.255)
он так же просто пропускает Ввод текста.
*/
#include <iostream>
#include <string>
using namespace std;
char Al[] = "ABCDEFGHIKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz";
char MyText[260] = ""; // введенный текст
char ResText[516] = ""; // полученный текст
char Pust = 'X'; // пустышка
char Resh[5][10];
char txt[] = "";
void CreateR() //создание и вывод решётки шифрования
{
int i, j, p = 0;
for (i = 0; i < 5; i++)
{
cout << "\n";
for (j = 0; j < 10; j++)
{
Resh[i][j] = Al[p++];
cout << Resh[i][j];
}
}
}
void CmpJ (char *pChar)
{
if ((*pChar == 'J') || (*pChar == 'j'))
(*pChar)--; //-> I/i
}
void EditText() //вставка пустышек и проверка текста на чётность
{
char text[260];
int i, j;
for (j=i=0; MyText[i];)
{
CmpJ(&MyText[i]);
if (MyText[i+1])
{
CmpJ(&MyText[i+1]);
if (MyText[i] != MyText[i+1])
{
text[j++] = MyText[i++];
text[j++] = MyText[i++];
}
else
{
text[j++] = MyText[i++];
text[j++] = Pust;
}
}
else
{
text[j++] = MyText[i++];
text[j++] = Pust;
}
}
text[j] = 0;
strcpy_s(MyText, text, 256);
}
void Encrypt() //шифрование
{
// индексы букв в столбцах
int ind_x1 = 0;
int ind_y1 = 0;
int ind_x2 = 0;
int ind_y2 = 0;
unsigned int k = 0;
char txt[260];
strcpy_s(txt, MyText, 256);
while (k<strlen(txt))
{
for (int l = 0; l<5; l++)
for (int m = 0; m<10; m++)
{
if (txt[k] == Resh[l][m])
{
ind_x1 = l;
ind_y1 = m;
}
if (txt[k + 1] == Resh[l][m])
{
ind_x2 = l;
ind_y2 = m;
}
}
// Если буквы находятся в одной строке
if (ind_x1 == ind_x2)
{
if (ind_y1 == 9)
{
ResText[k] = Resh[ind_x1][0];
ResText[k + 1] = Resh[ind_x2][ind_y2 + 1];
}
else if (ind_y2 == 9)
{
ResText[k] = Resh[ind_x1][ind_y1 + 1];
ResText[k + 1] = Resh[ind_x2][0];
}
else
{
ResText[k] = Resh[ind_x1][ind_y1 + 1];
ResText[k + 1] = Resh[ind_x2][ind_y2 + 1];
}
}
// Если буквы находятся в одном столбце
else if (ind_y1 == ind_y2)
{
if (ind_x1 == 4)
{
ResText[k] = Resh[0][ind_y1];
ResText[k + 1] = Resh[ind_x2 + 1][ind_y2];
}
else if (ind_x2 == 4)
{
ResText[k] = Resh[ind_x1 + 1][ind_y1];
ResText[k + 1] = Resh[0][ind_y2];
}
else
{
ResText[k] = Resh[ind_x1 + 1][ind_y1];
ResText[k + 1] = Resh[ind_x2 + 1][ind_y2];
}
}
// Если буквы находятся в разных строках и разных столбцах
else
{
ResText[k] = Resh[ind_x1][ind_y2];
ResText[k + 1] = Resh[ind_x2][ind_y1];
}
k = k + 2;
}
ResText[k] = 0;
}
void Decrypt() //расшифровка
{
// индексы букв в столбцах
int ind_x1 = 0;
int ind_y1 = 0;
int ind_x2 = 0;
int ind_y2 = 0;
unsigned int k = 0;
char txt[260];
strcpy_s(txt, ResText, 256);
while (k<strlen(txt))
{
for (int n = 0; n<5; n++)
for (int o = 0; o<10; o++)
{
if (txt[k] == Resh[n][o])
{
ind_x1 = n;
ind_y1 = o;
}
if (txt[k + 1] == Resh[n][o])
{
ind_x2 = n;
ind_y2 = o;
}
}
// Если буквы находятся в одной строке
if (ind_x1 == ind_x2)
{
if (ind_y1 == 0)
{
ResText[k] = Resh[ind_x1][9];
ResText[k + 1] = Resh[ind_x2][ind_y2 - 1];
}
else if (ind_y2 == 0)
{
ResText[k] = Resh[ind_x1][ind_y1 - 1];
ResText[k + 1] = Resh[ind_x2][9];
}
else
{
ResText[k] = Resh[ind_x1][ind_y1 - 1];
ResText[k + 1] = Resh[ind_x2][ind_y2 - 1];
}
}
// Если буквы находятся в одном столбце
else if (ind_y1 == ind_y2)
{
if (ind_x1 == 0)
{
ResText[k] = Resh[4][ind_y1];
ResText[k + 1] = Resh[ind_x2 - 1][ind_y2];
}
else if (ind_x2 == 0)
{
ResText[k] = Resh[ind_x1 - 1][ind_y1];
ResText[k + 1] = Resh[4][ind_y2];
}
else
{
ResText[k] = Resh[ind_x1 - 1][ind_y1];
ResText[k + 1] = Resh[ind_x2 - 1][ind_y2];
}
}
// Если буквы находятся в разных строках и разных столбцах
else
{
ResText[k] = Resh[ind_x1][ind_y2];
ResText[k + 1] = Resh[ind_x2][ind_y1];
}
k = k + 2;
}
ResText[k] = 0;
}
void main()
{
int d;
bool loop=true;
while(loop)
{
printf("\n\nVvedite komandu:\n1-Sozdanie tablici perekodirovki\n2-Vvod teksta\n3-Shivrovanie i vivod\n4-Deshifrovanie i vivod\n0-Vihod\n");
cin >> d;
switch (d)
{
case 1:
CreateR();
cout << "\n DONE!";
break;
case 2:
printf("Vvedite tekst: ");
scanf_s("%s",&MyText, 256);
//cin >> MyText;
EditText();
break;
case 3:
Encrypt();
printf("\n%s", ResText);
break;
case 4:
Decrypt();
printf("\n%s", ResText);
break;
default:
loop = false;
}
}
}
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен