Реализовать приложение, извлекающее секретное сообщениеиз входного файла. Известно, чтодля скрытного внедрения данных используется регистр символа. Если буква в нижнем регистре – это соответствует «0», если буква в заглавном регистре – это соответствует «1». Очередной символ секретного сообщения составляется из 8-ми битов, которые формируют код этого символа. В шифровании используются только буквы русского или английского алфавита. Знаки препинания и цифры не учитываются.
Указание:
Приложениеразрабатывается на базе реализованного шаблона чтения из файла. Для получения шифрованного текста необходимо вызвать функцию:
voidGetCryptoText(char *massiv, int *resultlen);
massiv–указатель на массив символов, который будет заполнен сообщением после возврата из функции (не менее 500 байт);
resultlen–указатель на целочисленную переменную, которая будет равна количеству записанных в massiv во время выполнения функции байт.
Декодированное сообщение необходимо вывести на консоль.
Для проверки символа, является ли он буквой, используйте функцию
intiswalpha(unsigned char c);
Для перевода символов в верхний и нижний регистр используйте функции
inttowupper(unsigned char c);
inttowlower(unsigned char c);
Для корректной работы строки, содержащие русские буквы, должны быть объявлены как unsignedchar.
Заметим, что если вы работаете со средой обработки VisualStudio, то необходимо обратить внимание на настройку проекта (правой кнопкой на проекте, «Свойства»): параметр «CharacterSet» должен быть установлен в «UseMulti-ByteCharacterSet».
Переберем все элементы массива кодированных символов и запишем в новый массив «1», если символ в верхнем регистре, иначе запишем «0».
char *openmass=new char[size+1];
for(inti=0;i
{
if ( toupper(cryptomass[i]) == cryptomass[i])
openmass[i]|=1;
else
openmass[i]=0;
}
Наложимограничивающееусловие «Знакипрепинанияицифрынеучитываются», что производится установкой блокирующего условия или цикла, пропускающего очередной символ кодированного массива в случае, если он является знаком препинания или цифрой:
while(!iswalpha((unsigned char)cryptomass[i]) &&i
i++;
Таким образом,получаем рабочий цикл, переводящий массив кодированных байт в массив из 0 и 1, представляющих из себя символы русского алфавита, записанные в двоичном представлении. Последним действием по конструированию алгоритма и написанию программы является запись открытого текста в виде привычных символов, что производится с помощью сдвиговых операций. Необходимо пройти выходной массив один раз от начала до конца записывая 0 и 1 по 8 элементов в один байт с использованием, к примеру, вот такого выражения:
openmass[l]|=1<<(7-j);
Здесь j – это инкрементная переменная, принимающая значения от 0 до 7 и позволяющая с помощью операции сдвига сместить двоичную единицу последовательно по всем возможным значениям в байте (1, 2, 4, 8, 16, 32, 64, 128). Слева от равенства используется знак поразрядного сложения, задача которого установить в результирующем байте декодированной последовательности битовую единицу в соответствующее место (см. рис. 1).
Задача решена, но для максимальной оценки необходимо провести оптимизацию, чтобы устранить лишнее преобразование из массива байт в массив 0 и 1, а затем обратно в массив байт. Получается, что входной массив преобразуется в меньший в 8 раз по объёму (если не учитывать знаки пунктуации и цифры). Значит необходимо создать выходной массив сразу и заполнять его последовательно в байтовом представлении. Рабочий цикл приведен ниже:
int _tmain(intargc, _TCHAR* argv[]){
setlocale(LC_ALL,"Russian");
unsigned char cryptomass[5000];
intcryptomasssize=0;
////////////////////////////////////////////////////////////
GetCryptoText(cryptomass,&cryptomasssize);
//Запишите своё решение ниже
//...
char *openmass;
int size=strlen((char*)cryptomass);
unsigned char mask=1;
int k=0, l=0, t=0;
openmass=new char[size/8+1];
for(inti=0;i
openmass[l]=0;
for(int j=0;j<8;j++) {
while(!iswalpha((unsigned char)cryptomass[i]) &&i
i++;
if ( toupper(cryptomass[i]) == cryptomass[i])
openmass[l]|=1<<(7-j);
i++;
}
l++;
i--;
}
openmass[size/8]='\0';
printf("%s\n",openmass);
////////////////////////////////////////////////////////////
return 0;
}