помогите пожалуйста разобраться на примере этого текста подробно
gil bil pes
gil bil pes
Код:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <iostream>
#define max 10000//количество слов
#define len 25//максимальная длина слова
using namespace std;
FILE *PF;//файл данных
char nch='\n';//читаемый символ
int nst=0;//номер строки
//для хранения слов
char stec[max][len]; //слова
char rez[max][len*8];//двоичный код
int top=0;//вершина стека
void get();//для считывания файла и его шифрования
void world();//процедура для чтения слов
void Shifr();//шифруем
void Deshifr();//дешифруем
char* Bit(char x);//возвращает двоичный код символа
int Sim(char binary[8]);//преобразует 8 бит кода символа в 10 код символа
void main(int ac,char* av[])
{
setlocale(LC_ALL, "Russian");//подключение русского языка
//проверка задан ли файл для работы
if (ac==1) //если не задан(количество аргументов 1-имя программы)
printf("Файл для шифрования\дешифрования не задан\n");
else //если задан
{
PF=fopen(av[1],"rt");//открыть файл
//проверка открытия файла для работы
if (PF==0) //если файл не открыт
{
printf("Файл не открыт\n");
}
else //если файл открыт
{
char ch='\n';//обнудение переменной
//выбор действия
while (ch!='1' && ch!='2')
{
printf("1.Шифровать файл\n");
printf("2.Дешифровать файл\n");
ch=getch();
cout<<ch<<endl;
}
//обработка действия
if (ch=='1')
{
get();//считаем данные
fclose(PF); //закроем фал
Shifr();//зашифруем данные
//вывод результата шифрования
PF=fopen("Shifr.dan","wt");
for(int i=top-1;i>=0;i--)
fprintf(PF,"%s ",rez[i]);
fclose(PF);
}
else
{
Deshifr();//дешифруем данные
fclose(PF);
//вывод результата дешифрования
PF=fopen("Deshifr.dan","wt");
for(int i=top-1;i>=0;i--)
fprintf(PF,"%s ",stec[i]);
fclose(PF);
}
}
}
system("pause");
}
//для считывания файла перед шифрованием
void get()
{
nch=getc(PF);
while(nch!=EOF)
{
while(isspace(nch)) //если пробельный символ
//while(nch==' '|| nch=='\n' || nch=='\t')
{
if(nch=='\n')
{
nst++;
break;
}
nch=getc(PF);
}
if (isalpha(nch) || isdigit(nch)|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
//if((nch>47 && nch<58) || (nch>96 && nch<123) || (nch>'А' && nch<'Я')|| (nch>'а' && nch<'я')|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
world();
else
{
printf("Недопустимый символ в строке %i\n",nst+1);
nch=getc(PF);
}
}
return;
}
//процедура разделения на слова
void world()
{
char tx[40];
int i;
char *p;
p=tx;//запоминаем указатель на строку
while (isalpha(nch) || isdigit(nch)|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
//while ((nch>47 && nch<58) || (nch>96 && nch<123) || (nch>'А' && nch<'Я')|| (nch>'а' && nch<'я')|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' )//пока символ или разделитель - читаем
{
*(p++)=nch;//заносим данные в строку
nch=getc(PF);//читаем следующий символ
}
*p='\0';//заносим признак окончания строки
strcpy(stec[top],tx);//копируем результат в стек данных
top++;//увеличиваем счетчик
}
//процедура шифрования
void Shifr()
{
//перевод символов в бинарный код
for(int i=top-1;i>=0;i--)
{
//printf("%s\n",stec[i]);//проверка начального слово(исползовалась при отладке)
for (int j=0; j<strlen(stec[i]); j++)
{
if (j==0)//если разбираем первый символ
strcpy(rez[i],Bit(stec[i][j]));//скопируем двоичный код в строку
else//если последующие символы
strcat(rez[i],Bit(stec[i][j]));//добавим код к строке
//printf(" - %c - %i\n",stec[i][j],stec[i][j]);//проверочный вывод символа и десятичного кода(использовалось при отладке)
}
//printf("%s\n",rez[i]);//выведем бинарный код(использовалось при отладке)
}
//временнный вывод для проверки результата
/*FILE *PF1=fopen("Temp.dan","wt");
for(int i=top-1;i>=0;i--)
fprintf(PF1,"%s ",rez[i]);
fclose(PF1); */
//определение значимого бита
char ch;
ch='\n';
while(!isdigit(ch) || (int)(ch-'0')>7)
{
printf("Введите № символ для шифрования 0-7\n");
ch=getch();
cout<<ch<<endl;
}
//кодирование
//берем двоичный код симовлов
for(int i=top-1;i>=0;i--)
{
//cout<<rez[i]<<endl;
for(int j=0; j<strlen(rez[i]); j++)
{
char simvol =96 + rand()%27;//случайный символ английского алфавита
//char simvol = 'a';//символ 'а'
//проверочный вывод до замены бита(для отладки)
//cout<<j<<")"<<rez[i][j]<<endl<<simvol<<endl<<Bit(simvol)<<endl;
if (rez[i][j]=='0')
{
switch (ch)//Оператор & обычно применяют, чтобы обнулить один или несколько битов.
{
case '0' : simvol = simvol&(~(1<<0)); break;
case '1' : simvol = simvol&(~(1<<1)); break;
case '2' : simvol = simvol&(~(1<<2)); break;
case '3' : simvol = simvol&(~(1<<3)); break;
case '4' : simvol = simvol&(~(1<<4)); break;
case '5' : simvol = simvol&(~(1<<5)); break;break;
case '6' : simvol = simvol&(~(1<<6)); break;
case '7' : simvol = simvol&(~(1<<7)); break;
}
}
else
{
switch (ch)//Оператор | обычно используют для установки заданных битов переменной в единицу.
{
case '0' : simvol = simvol|(1<<0); break;
case '1' : simvol = simvol|(1<<1); break;
case '2' : simvol = simvol|(1<<2); break;
case '3' : simvol = simvol|(1<<3); break;
case '4' : simvol = simvol|(1<<4); break;
case '5' : simvol = simvol|(1<<5); break;
case '6' : simvol = simvol|(1<<6); break;
case '7' : simvol = simvol|(1<<7); break;
}
}
//проверочный вывод после замены бита(для отладки)
//cout<<j<<")"<<endl<<simvol<<endl<<Bit(simvol)<<endl;
rez[i][j]=simvol;//замена символа в результате
}
//cout<<rez[i]<<endl;//проверочный вывод результата
}
}
void Deshifr()
{
//определение значимого бита
char ch;
ch='\n';
while(!isdigit(ch) || (int)(ch-'0')>7)
{
printf("Введите № символ для дешифрования 0-7\n");
ch=getch();
cout<<ch<<endl;
}
//чтение файла
nch=getc(PF);
int i=0;
int j=0;
while(nch!=EOF)
{
if(nch==' ')//т.к. слова разделены пробелами
{
nch=getc(PF);
i++;
j=0;
}
else
{
char temp[20];
strcpy(temp, Bit(nch));//получим его бинарный код
rez[i][j] = temp[7-(int)(ch-'0')];//извлекаем нужный бит
j++;
nch=getc(PF);//считаем символ
}
}
top=i;
//проверочный вывод для отладки
/*for(i=top-1;i>=0;i--)
cout<<rez[i]<<"\n";*/
for (i=0; i<top; i++)
//for(i=top-1;i>=0;i--)
for(j=0; j<strlen(rez[i])/8; j++)
{
char t[8];
for(int a=0; a<8; a++)
t[a]=rez[i][j*8+a];
//cout<<Sim(t)<<" - "<<(char)Sim(t)<<endl;//проверочный вывод для отладки
stec[i][j]=(char)Sim(t);//сохранение результата
}
}
char* Bit(char x)
{
char tx[20];
for (int i=sizeof(x)*8-1; i>=0; --i)
{
tx[sizeof(x)*8-1-i]=((x>>i)&1)+'0';
//cout<<(int)((x>>i)&1);был проверочный код
}
tx[sizeof(x)*8]='\0';//символ конца строки
//cout<<endl<<tx;//проверочный вывод на экран
return tx;
}
//преобразует 8 бит кода в 10 код числа
int Sim(char binary[8])
{
int number = 0;
int mult = 1;
for(int i = 7; i>=0; i--, mult *= 2)
{
if(binary[i] == '1') number += mult;
}
//cout << number << endl;//проверочный вывод
return number;
}