Консультация № 190125
22.11.2016, 20:04
0.00 руб.
22.11.2016, 20:22
0 2 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Данный алгоритм реализует шифр плейфера, но у меня возникли две проблемы:
1) при дешифровке программа приписывает рандомный символ в конце( я думаю что моя реализация шифрования шифрует нулевой символ массива введённого текста)
2) если я реализую ввод текста через scanf("%s",&MyText); тогда компилятор выдаёт мне ошибку "rror C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead" как я понял,что просит установить scanf_s,но если я его установлю то при выборе пункта "Ввод текста" в меню программы он просто его пропускает,а также хотелось бы вводить строку чтобы кодировалась строка но также реализуя ввод через cin.getline(MyText.255) он так же просто пропускает Ввод текста.
[code h=200]#include <iostream>
#include <string>
using namespace std;

char Al[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char MyText[] = ""; // введенный текст
char Key[] = ""; // введенный ключ
char R[5][10]; // полученная решетка
char ResText[] = ""; // полученный текст
char Pust[] = ""; // пустышка
char Resh[10][16];
char Alphabet[] = "";
char txt[] = "";
void CreateR() //создание и вывод решётки шифрования
{
int p = 0;
for (int i = 0; i < 5; i++)
{

for (int j = 0; j < 10; j++)
{
Resh[i][j] = Al[p]; p++;
}
}
for (int i = 0; i<5; i++) {
cout << "\n";
for (int j = 0; j<10; j++) cout << Resh[i][j];
}
}

void EditText() //вставка пустышек и проверка текста на чётность

{

int Len = strlen(MyText);

if (Len % 2 != 0)

strcat_s(MyText, Pust);

}

void Encrypt() //шифрование

{

// индексы букв в столбцах

int ind_x1 = 0;

int ind_y1 = 0;

int ind_x2 = 0;

int ind_y2 = 0;

unsigned int k = 0;

char txt[20] = "\0";

for (unsigned int d = 0; d < strlen(MyText); d++)

txt[d] = MyText[d];

for (unsigned int d = 0; d < strlen(ResText); d++)

ResText[d] = ' ';

if (strlen(txt) % 2 != 0)

txt[strlen(txt)] = Pust[0];

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];

}

}

// Если буквы находятся в одном столбце

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];

}

}

// Если буквы находятся в разных строках и разных столбцах

if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))

{

ResText[k] = Resh[ind_x1][ind_y2];

ResText[k + 1] = Resh[ind_x2][ind_y1];

}

k = k + 2;

}

}

void Decrypt() //расшифровка

{

// индексы букв в столбцах

int ind_x1 = 0;

int ind_y1 = 0;

int ind_x2 = 0;

int ind_y2 = 0;

unsigned int k = 0;

char txt[20] = "\0";

for (unsigned int d = 0; d<strlen(ResText); d++)

txt[d] = ResText[d];

for (unsigned int d = 0; d<strlen(txt); d++)

ResText[d] = ' ';

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];

}

}

// Если буквы находятся в одном столбце

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];

}

}

// Если буквы находятся в разных строках и разных столбцах

if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))

{

ResText[k] = Resh[ind_x1][ind_y2];

ResText[k + 1] = Resh[ind_x2][ind_y1];

}

k = k + 2;

}

}



void main()

{

int d;

L1:

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!";

goto L1;

case 2:

printf("Vvedite tekst: ");
cin >> MyText;
void EditText();
goto L1;
case 3:
Encrypt();
printf("\n%s", ResText);
goto L1;
case 4:
Decrypt();

printf("\n%s", ResText);

goto L1;

default:

break;

}

}[/code]

Обсуждение

давно
Посетитель
7438
7205
22.11.2016, 20:24
общий
Адресаты:
И зачем аж 3 одинаковых вопроса? Чтобы наверняка?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
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]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа