Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты в разделе

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 364
∙ повысить рейтинг »
Степанов Иван /REDDS
Статус: 3-й класс
Рейтинг: 152
∙ повысить рейтинг »
CradleA
Статус: Профессионал
Рейтинг: 44
∙ повысить рейтинг »

∙ С / С++

Номер выпуска:1888
Дата выхода:03.12.2016, 13:45
Администратор рассылки:Андрей Кузнецов aka Dr_Andrew (Старший модератор)
Подписчиков / экспертов:23 / 16
Вопросов / ответов:1 / 1

Консультация # 190125: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Данный алгоритм реализует шифр плейфера, но у меня возникли две проблемы: 1) при дешифровке программа приписывает рандомный символ в конце( я думаю что моя реализация шифрования шифрует нулевой символ массива введённого текста) 2) если я реализую ввод текста через scanf...

Консультация # 190125:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Данный алгоритм реализует шифр плейфера, но у меня возникли две проблемы:
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) он так же просто пропускает Ввод текста.

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

	}

}

Дата отправки: 22.11.2016, 20:04
Вопрос задал: dteplyakova80 (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, 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 требуют указания длины приемного буфера, как раз, для предотвращения переполнения буфера!

/*
	Данный алгоритм реализует шифр Плейфера, 
	но у меня возникли две проблемы:
	  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;
		}
	}
}

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 24.11.2016, 19:24
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное