Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C/ Visual c++ 6.0/Криптография]


Автор: Alma 17.3.2009, 13:09
Нужно зашифровать текст, хранящийся в текстовом файле и состоящий из русских букв, цифр и знаков препинания. Зашифрованный текст записать в другой файл. Ещё нужно написать программу для расшифровки зашифрованного файла.
Алгоритм: каждая буква имеет номер. Маска вводится с клавиатуры  и накладывается на текст, пока он не кончится. Складываем номер буквы текста с номером буквы маски, получаем номер новой буквы. Если номер больше длины алфавита, то отнимаем от него длину - это и будет номер новой буквы

Подскажите как исправить программу, работает неправильно, не понимаю почему.
Вот что у меня получилось
 
Код

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>

FILE *finp, *fout1;
// *out2;
char alfavit[]={'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с',
                'т','у','ф','х','ц','ч','ш','щ','ь','ы','ъ','э','ю','я','.',',',';',':','-','!','?',' ',
                '1','2','3','4','5','6','7','8','9','0'};


int nomer(char a)              //ф-ия к-ая должна сравнивать очередной символ с алфавитом и определять её номер
{  
     for(int i=0;i<strlen(alfavit);i++)  
       
          {   if(a==alfavit[i])
         
                 return(i);
         } 

}

int nomer_res(int a, int b)                //функция к-ая определяет номер буквы, которая будет шифровать наш очередной символ
{   
    int result=0;
     result=a+b;
     if(result<strlen(alfavit))
        return(result);
     else
        return(result-(strlen(alfavit)));
}     
///////////////////////////////////////////////////////////////////////////////////////////////////
void main(){

char maska[30] ;
char str[20], str1[100]="";

int dl_m;
int k,i,l, res;

printf("Vvedite masku ne menee 5 simvolov\n Maska=");
gets(maska);

dl_m=strlen(maska);       //определяем длину маски, такое же количество символов будем считывать из файла

///////////////////////////////////////////////////////////////////////////////////////////////////////
if(!(finp=fopen("inp.txt","r")))
{ printf("Input file opening error\n");
   exit(-1);
}

if(!(fout1=fopen("out1.txt","w")))
{ printf("Input file opening error\n");
   exit(-1);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////

while(!feof(finp))
 
{     
     if(fgets(str,dl_m+1,finp))
           l=0;
        {for(i=0;i<dl_m;i++)
      {        res=0;
               int a=nomer(str[i]);
               int b=nomer(maska[i]);
               res=nomer_res(a,b);

//  printf(" %d/%d  ",a,b);                 //при выводе этих значений получаются совсем не те, к-ые должны получаться в соответствии с 
                                                         // алфавитом

               str1[l]=alfavit[res];
                l++;
      }  

            fputs(str1,fout1);

        }

}

fclose(finp);
fclose(fout1); 
}

Автор: zim22 17.3.2009, 15:05
вы не везде return возвращали.

Код

int nomer(char a)              //ф-ия к-ая должна сравнивать очередной символ с алфавитом и определять её номер
{  
    bool flag = false;
    int need_i = 0;

     for(int i=0;i<strlen(alfavit);i++)         
          {   if(a==alfavit[i])    
                { 
                 need_i = i;
                 flag = true;
                 break;
                }
         } 
     if (!flag)
         printf("blablabla\n");

     return need_i;

}

Автор: Alma 17.3.2009, 17:58
Теперь с помощью вашей функции правильно определяются номера букв из текста, за исключением самой первой , к-ая обнуляется. Буквы из маски также все обнуляются, поэтому текст не шифруется, а остаётся исходный...

Автор: zim22 17.3.2009, 19:12
Цитата(Alma @  17.3.2009,  17:58 Найти цитируемый пост)
Теперь с помощью вашей функции 

Сир, я настаиваю, это ваша функция.  я её чуть-чуть изменил только.
если вопрос получен - пометьте тему решённой.

Автор: Alma 17.3.2009, 19:23
В том то и дело что не получен(.Спасибо за помощь , стало немного лучше, но всё равно программа не работает так как надо. Если можете помогите пожалуста!

Автор: zim22 17.3.2009, 21:49
Alma, прогу на С обязательно писать? или можно на С++?

Автор: zim22 17.3.2009, 22:05
поменяй
Код
  if(fgets(str,dl_m+1,finp))
           l=0;
        {for(i=0;i<dl_m;i++)


на 
Код
if(fgets(str,dl_m+1,finp)){
           l=0;
        for(i=0;i<dl_m;i++)

Автор: Alma 17.3.2009, 22:28
Поменяла, получается тоже самое, не помогает((( Лучше конечно прогу на С.

Автор: zim22 18.3.2009, 10:05
всё работает
Код
#include <locale.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>

FILE *finp, *fout1;
// *out2;
char alfavit[]={'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с',
                'т','у','ф','х','ц','ч','ш','щ','ь','ы','ъ','э','ю','я','.',',',';',':','-','!','?',' ',
                '1','2','3','4','5','6','7','8','9','0'};


int nomer(char a)              //ф-ия к-ая должна сравнивать очередной символ с алфавитом и определять её номер
{  
    bool flag = false;
    int need_i = 0;

     for(int i=0;i<strlen(alfavit);i++)         
          {   if(a==alfavit[i])    
                { 
                 need_i = i;
                 flag = true;
                 break;
                }
         } 
     if (!flag)
         printf("error!\n");

     return need_i;

}

int nomer_res(int a, int b)                //функция к-ая определяет номер буквы, которая будет шифровать наш очередной символ
{   
    int result=0;
     result=a+b;
     if(result<strlen(alfavit))
        return(result);
     else
        return(result-(strlen(alfavit)));
}   
void Convert866to1251(char *dest)
{
    const char t[] =
        "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп"
        "                                                "
        "рстуфхцчшщъыьэюяЁё"; // t - строка длиной 128 символов

    for(int i = 0; dest[i]!=0; i++ )
    {
        int j = (unsigned char)dest[i] - 128; // получаем код символа - 128 (это будет позиция в строке t)
        if( j>=0 ) // если код символа был больше 127 (т.е. может понадобится его перекодировать)
            if( t[j]!=' ' || t[j] != '.' ) // если в строке t не пробел (т.е. это буква, которую нужно заменить на нужную)
                dest[i] = t[j]; // то заменяем
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
void main(){    

char maska[30] ;
char str[20], str1[100]="";

int dl_m;
int k,i,l, res;

printf("Vvedite masku (1 simvol minimum)\n Maska=");
//gets(maska);
setlocale(LC_ALL,".866");
gets(maska);
Convert866to1251(maska);

dl_m=strlen(maska);       //определяем длину маски, такое же количество символов будем считывать из файла

///////////////////////////////////////////////////////////////////////////////////////////////////////
if(!(finp=fopen("inp.txt","r")))
{ printf("Input file opening error\n");
   exit(-1);
}

if(!(fout1=fopen("out1.txt","w")))
{ printf("Input file opening error\n");
   exit(-1);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////

while(!feof(finp))
 
{     
     if(fgets(str,dl_m+1,finp)){
           l=0;
        for(i=0;i<strlen(str);i++)
      {        res=0;
               int a=nomer(str[i]);
               int b=nomer(maska[i]);
               res=nomer_res(a,b);

//  printf(" %d/%d  ",a,b);                 //при выводе этих значений получаются совсем не те, к-ые должны получаться в соответствии с 
                                                         // алфавитом

               str1[l]=alfavit[res];
                l++;
      }  
        
            str1[l]= '\0';
            fputs(str1,fout1);

        }

}

fclose(finp);
fclose(fout1); 
}


Автор: Alma 18.3.2009, 19:26
Спасибо огромное!Действительно всё работает!

Автор: zim22 18.3.2009, 21:52
Код

 if( t[j]!=' ' || t[j] != '.' ) // если в строке t не пробел (т.е. это буква, которую нужно заменить на нужную)

чтобы всё действительно работало smile, добавь ещё логическое условие ИЛИ не только для пробела и точки, но и для других символов, которые не являются русскими буквами. (английские буквы добавлять не надо).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)