C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: шифратор/дешифратор английского текста, метод Цезаря  (Прочитано 3564 раз)
Irisitas
новенький


Сказали спасибо: +0/-0
Offline

Сообщений: 2


« : 18 Сентябрь 2012, 22:25:47 »

Необходимо сделать шифратор-дешифратор текстов на английском языке c чувствительностью к болшьим и маленьким буквам . Есть уже готовый с использованием русского алфавита(код прилагается.)

Пытаюсь переделать под английский алфавит из 26 букв (код прилагается), ничего не выходит-как русский текст шифровало так и шифрует, англиийский не преобразовывает вообще.

исходный код с шифрованием\дешифрованием русского текста

Код:
TForm1 *Form1;
AnsiString MyFName="", //Имя открываемого файла
 SaveMyFName=""; //Имя сохраняемого файла
 void coding(); //Функция зашифровки
 void decoding(); //Функция расшифровки
 int decoding_findsdv(); //Функция нахождения ключа
 bool keyproverka(); //Функция проверки корректности ввода ключа
//-----------------имена временных файлов-----------------------
 char *TmpFName="cipher_cesar_temp.tmp",
 *TmpFName1="cipher_cesar_temp_1.tmp";
 bool savdet=0; //сохранен ли файл

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// keyproverka(); //Проверка корректности ввода ключа
 if(keyproverka())
 {
 Memo1->Lines->SaveToFile(TmpFName);
 if(RadioGroup1->ItemIndex==0)
 coding();
 if(RadioGroup1->ItemIndex==1)
 decoding();
 }     
  else {Edit1->Text=""; }
   }
//---------------------------------------------------------------------------
void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
if(RadioGroup1->ItemIndex==0)
 {
 Label1->Caption="или он будет выбран рандомом";
 Memo2->Lines->Text="";
 Label2->Caption="Ключ = ";
 savdet=0;
 }
 if(RadioGroup1->ItemIndex==1)
 {
 Label1->Caption="или он будет найден автоматически";
 Memo2->Lines->Text="";
 Label2->Caption="Ключ = ";
 savdet=0;
 }
}
   //---------Проверка корректности ввода----------------------------------------
bool keyproverka()
{ bool prov;
 prov=1;
 int code,i;
 char *editkey2="";
 AnsiString editkey1="";
 if(Form1->Edit1->Text!="")
 {
 editkey1=Form1->Edit1->Text;
 editkey2=editkey1.c_str();
 i=0;
 while(editkey2[i]!=NULL)
 {
 code=editkey2[i];
 if(code<48||code>57) prov=0;
 i++;
 }
 }
 return prov;
}
[color="#FFFACD"]//---------------------Функция кодирования текста-----------------------------
void coding()
{
 char b; long sdvig;
 Form1->Label2->Caption="" ;
 if(Form1->Edit1->Text!="")
 {
 sdvig=StrToInt(Form1->Edit1->Text);
 if(sdvig>32)
 sdvig%=32;
 }
else sdvig=random(32)+1;
 ifstream tempfile(TmpFName);
 ofstream tempfile1(TmpFName1);
 while(!tempfile.eof())
 {
 b=0;
 tempfile.get(B) ;
 if(b>=-64&&b<=-33||b==-88) //Сдвиг для больших букв
 {
 if(b==-88) b=-59+sdvig ; //Если попадается буква Ё
 else b+=sdvig;
 if(b>-33) b-=32;
 }
 if(b>=-32&&b<=-1) //Сдвиг для маленьких букв
 {
 b+=sdvig;
 if(b>-1) b-=32;
 }
 tempfile1.put(B);
 }
 tempfile.close(); //Закрытие временного файла
 remove(TmpFName); //Удаление временного файла
 tempfile1.close(); //закрытие закодированного файла
 Form1->Memo2->Lines->LoadFromFile(TmpFName1);
 remove(TmpFName1); //Удаление временного файла
 Form1->Label2->Caption= "Ключ = "+IntToStr(sdvig) ;
}
/*-------------------Функция декодирования текста-----------------------*/
void decoding()
{
 int sdvig=0, //сдвиг по алфавиту
         i,j;
 char b;
 sdvig=decoding_findsdv();
 //----------------Расшифровка текста------------------------------
 ifstream tempfile2(TmpFName); //Открытие файла для чтения
 ofstream tempfile1(TmpFName1); //Открытие файла для записи
 while(!tempfile2.eof())
 {
 b=0;
 tempfile2.get(B) ; //Считывание кода очередного символа
 if(b>=-64&&b<=-33||b==-88) //Сдвиг для больших букв
 {
 if(b==-88) b=-59-sdvig ; //Если попадается буква Ё
 else b-=sdvig; //Сдвиг
 if(b<-64) b+=32; //После буквы А
 }
 if(b>=-32&&b<=-1) //Сдвиг для маленьких букв
 {
 b-=sdvig; //Сдвиг
 if(b<-32) b+=32; //После буквы а
 }

 tempfile1.put(B); //Запись расшифрованной буквы
 }
 tempfile2.close(); //Закрытие временного файла
 remove(TmpFName); //Удаление временного файла
 tempfile1.close(); //закрытие закодированного файла
 Form1->Memo2->Lines->LoadFromFile(TmpFName1);
 remove(TmpFName1); //Удаление временного файла
 Form1->Label2->Caption= "Ключ = "+IntToStr(sdvig) ;
}

//--------------Нахождение ключа-------------------------------
int decoding_findsdv()
{
 int counter=0, //счетчик количества букв
 sdvig=0, //сдвиг по алфавиту
        i,j;
 double delta=0,mindelta=50 , //Разница между частотами букв в тексте и в языке
 freq[32]; //Массив для подсчета частот вхождения букв в текст для каждой буквы
 double frequency[32]={0.074438, 0.016189, 0.050396, 0.019352, //А Б В Г
                 0.028179, 0.089613, 0.010010, 0.016637, //Д Е Ж З
                 0.074109, 0.014743, 0.032171, 0.037507, //И Й К Л
                 0.031160, 0.067640, 0.113329, 0.026275, //М Н О П
                 0.049378, 0.056569, 0.063209, 0.023785, //Р С Т У
                 0.001466, 0.009276, 0.004299, 0.014236, //Ф Х Ц Ч
                 0.006525, 0.004035, 0.000240, 0.017820, //Ш Щ Ъ Ы
                 0.016222, 0.004256, 0.007210, 0.019724}; //Ь Э Ю Я
 char b;

 Form1->Label2->Caption="" ;
 if(Form1->Edit1->Text!="")
 {
 sdvig=StrToInt(Form1->Edit1->Text);
 if(sdvig>32)
 sdvig%=32;
 }
 else
 {
/*--------------Подсчет общего количества букв в тексте-------------------*/
 ifstream tempfile(TmpFName);
 while(!tempfile.eof())
 {
 b=0;
 tempfile.get(B) ;
 if(b>=-64&&b<=-1||b==-88) counter++;
 }
 tempfile.close();
/*-----------------Обнуление счётчика частот------------------------------*/
 for(j=0;j<32;j++)
 freq[j]=0;
 /*-------Цикл нахождения сдвига по частотам букв для каждого сдвига----*/
 for(i=0;i<32;i++)
 {
 ifstream tempfile(TmpFName);
 while(!tempfile.eof())
 {
 tempfile.get(B) ;
 b-=i;
 if(b<-64) b+=64;
 /*----------Большие буквы-------------*/
 if(b>=-64&&b<=-33)
 freq[b+64]++;
 /*----------Маленькие буквы----------*/
 if(b>=-32&&b<=-1)
 freq[b+32]++;
 }
 tempfile.close();
 /*----Нахождение разницы между частотами букв текста и букв алфавита---*/
 for(j=0;j<32;j++)
 {
                 if (counter!=0)
 freq[j]/=counter;
 delta+=fabs(frequency[j]-freq[j]);
 freq[j]=0;
 }
 /*----запоминание минимальной разницы частот и размера сдвига ------*/
 if(delta  {
 mindelta=delta;
 sdvig=i;
 }
 delta=0;
 }
 }
 return sdvig;
 }

//---------------------------------------------------------------------------
код, в котором поменяла количество букв с 32 на 26

Код:
//---------------------Функция кодирования текста-----------------------------
void coding()
{
 char b; long sdvig;
 Form1->Label2->Caption="" ;
 if(Form1->Edit1->Text!="")
 {
 sdvig=StrToInt(Form1->Edit1->Text);
 if(sdvig>26)
 sdvig%=26;
 }
else sdvig=random(26)+1;
 ifstream tempfile(TmpFName);
 ofstream tempfile1(TmpFName1);
 while(!tempfile.eof())
 {
 b=0;
 tempfile.get(B) ;
 if(b>=-52&&b<=-27) //Сдвиг для больших букв
 {
 b+=sdvig;
 if(b>-27) b-=26;
 }
 if(b>=-26&&b<=-1) //Сдвиг для маленьких букв
 {
 b+=sdvig;
 if(b>-1) b-=26;
 }
 tempfile1.put(B);
 }
 tempfile.close(); //Закрытие временного файла
 remove(TmpFName); //Удаление временного файла
 tempfile1.close(); //закрытие закодированного файла
 Form1->Memo2->Lines->LoadFromFile(TmpFName1);
 remove(TmpFName1); //Удаление временного файла
 Form1->Label2->Caption= "Ключ = "+IntToStr(sdvig) ;
}
/*-------------------Функция декодирования текста-----------------------*/
void decoding()
{
 int sdvig=0, //сдвиг по алфавиту
         i,j;
 char b;
 sdvig=decoding_findsdv();
 //----------------Расшифровка текста------------------------------
 ifstream tempfile2(TmpFName); //Открытие файла для чтения
 ofstream tempfile1(TmpFName1); //Открытие файла для записи
 while(!tempfile2.eof())
 {
 b=0;
 tempfile2.get(B) ; //Считывание кода очередного символа
 if(b>=-52&&b<=-27) //Сдвиг для больших букв
 {
 b-=sdvig; //Сдвиг
 if(b<-52) b+=26; //После буквы А
 }
 if(b>=-26&&b<=-1) //Сдвиг для маленьких букв
 {
 b-=sdvig; //Сдвиг
 if(b<-26) b+=26; //После буквы а
 }
 tempfile1.put(B); //Запись расшифрованной буквы
 }
 tempfile2.close(); //Закрытие временного файла
 remove(TmpFName); //Удаление временного файла
 tempfile1.close(); //закрытие закодированного файла
 Form1->Memo2->Lines->LoadFromFile(TmpFName1);
 remove(TmpFName1); //Удаление временного файла
 Form1->Label2->Caption= "Ключ = "+IntToStr(sdvig) ;
}
//--------------Нахождение ключа-------------------------------
int decoding_findsdv()
{
 int counter=0, //счетчик количества букв
 sdvig=0, //сдвиг по алфавиту
        i,j;
 double delta=0,mindelta=50 , //Разница между частотами букв в тексте и в языке
 freq[26]; //Массив для подсчета частот вхождения букв в текст для каждой буквы
 double frequency[26]={0.0804, 0.0154, 0.0306, 0.0399, 0.1251, 0.0230, //A B C D E F
                       0.0196, 0.0549, 0.0726, 0.0016, 0.0067, 0.0414, //G H I J K L
                       0.0253, 0.0709, 0.0760, 0.0200, 0.0011, 0.0612, //M N O P Q R
                       0.0654, 0.0925, 0.0271, 0.0099, 0.0192, 0.0019, //S T U V W X
                       0.0173, 0.0009}; //Y Z
 char b;

 Form1->Label2->Caption="" ;
 if(Form1->Edit1->Text!="")
 {
 sdvig=StrToInt(Form1->Edit1->Text);
 if(sdvig>26)
 sdvig%=26;
 }
 else
 {
/*--------------Подсчет общего количества букв в тексте-------------------*/
 ifstream tempfile(TmpFName);
 while(!tempfile.eof())
 {
 b=0;
 tempfile.get(B) ;
 if(b>=-52&&b<=-1) counter++;
 }
 tempfile.close();
/*-----------------Обнуление счётчика частот------------------------------*/
 for(j=0;j<26;j++)
 freq[j]=0;
 /*-------Цикл нахождения сдвига по частотам букв для каждого сдвига----*/
 for(i=0;i<26;i++)
 {
 ifstream tempfile(TmpFName);
 while(!tempfile.eof())
 {
 tempfile.get(B) ;
 b-=i;
 if(b<-52) b+=52;
 /*----------Большие буквы-------------*/
 if(b>=-52&&b<=-27)
 freq[b+52]++;
 /*----------Маленькие буквы----------*/
 if(b>=-26&&b<=-1)
 freq[b+26]++;
 }
 tempfile.close();
 /*----Нахождение разницы между частотами букв текста и букв алфавита---*/
 for(j=0;j<26;j++)
 {
                 if (counter!=0)
 freq[j]/=counter;
 delta+=fabs(frequency[j]-freq[j]);
 freq[j]=0;
 }
Записан
golov67309v
Участник


Сказали спасибо: +5/-0
Offline

Сообщений: 8


« Ответ #1 : 19 Сентябрь 2012, 02:29:47 »

Ошибка в диапазонах у англ. букв

в coding д.б.:
Код
 if(b>=65&&b<=90)
{
b+=sdvig;
if(b>90) b-=26;
}
if(b>=97&&b<=122)
{
b+=sdvig;
if(b>122) b-=26;
}
 

в decoding д.б.:
Код
 if(b>=65&&b<=90)
{
b-=sdvig;
if(b<65) b+=26;
}
if(b>=97&&b<=122)
{
b-=sdvig;
if(b<97) b+=26;
}
 
Записан
Irisitas
новенький


Сказали спасибо: +0/-0
Offline

Сообщений: 2


« Ответ #2 : 19 Сентябрь 2012, 02:50:28 »

Ну, вроде заработало. Спасибо большое, сама бы я долго с этими диапазонами мучилась)
Записан
golov67309v
Участник


Сказали спасибо: +5/-0
Offline

Сообщений: 8


« Ответ #3 : 19 Сентябрь 2012, 03:02:01 »

Пожалуйста.
А чтобы не путаться с диапазонами чисел, лучше использовать диапазоны букв.
coding:
Код
 if(b>='A'&&b<='Z')
{
b+=sdvig;
if(b>'Z') b-=26;
}
if(b>='a'&&b<='z')
{
b+=sdvig;
if(b>'z') b-=26;
}
 

decoding:
Код
 if(b>='A'&&b<='Z')
{
b-=sdvig;
if(b<'A') b+=26;
}
if(b>='a'&&b<='z')
{
b-=sdvig;
if(b<'a') b+=26;
}
 
Записан
d7d1cd
Участник


Сказали спасибо: +59/-24
Offline

Сообщений: 1005


« Ответ #4 : 19 Сентябрь 2012, 07:00:40 »

А еще можно использовать RC4 и вообще не думать о том, что идет на шифровку.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.183 секунд. Запросов: 21.