Лабораторная работа №1
Основные принципы криптографии
Цель: Изучение алгоритмов шифрования, дешифрования и сжатия.
Ход работы
Реализовать шифрование и дешифрование сообщений при помощи алгоритма Хила и Плейфера и также сжатие файла по методу Шеннона Фано.
Содержимое файла function.h:
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <math.h>
#include <utility>
#include <map>
#include <cstdlib>
#include <vector>
using namespace std;
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char szWindowClass [] = "myWindowClass";
HWND hWnd;
int key[3][3]={1,2,2,3,4,5,6,7,8};
struct Simbol
{
char c;
int kol;
vector <int> code;
};
void fun( vector<Simbol> &general, vector<Simbol> &razb );
void displaybits(int k);
LRESULT CALLBACK HILA(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int i, j, d=0, x=0;
int ch[3];
char cl[3];
char file1[20]="D:\\shifr.txt";
char file2[20]="D:\\deshifr.txt";
map<int, char> alf;
map<char, int> alf2;
map<int, char> :: iterator ptr;
map<char, int> :: iterator ptr2;
ifstream In;
ofstream Out;
//Формирование алфавита
for (i=0; i<26; i++)
{
alf.insert(pair<int, char> (i, i+65));
alf2.insert(pair<char, int> (i+65, i));
}
In.open(file1);
Out.open(file2);
//Шифровка информации
while(!In.eof())
{
//считывание символов из файла
for (i=0; i<3; i++)
{
In>>cl[i];
if(In.eof())
{
j=0;
while(j!=i)
{
Out<<cl[j];
j++;
}
break;
}
}
if(In.eof())
break;
//нахождение символа в нашем алфавите
for (i=0; i<3; i++)
{
ptr2=alf2.find(cl[i]);
if ( ptr2!=alf2.end() )
cl[i]=(ptr2->second);
}
//Шифровка согласно ключу
for(i=0; i<3; i++)
{
ch[i]=0;
for(j=0; j<3; j++)
ch[i]+=cl[j]*key[i][j];
}
for(i=0; i<3; i++)
ch[i]=ch[i]%26;
for(i=0; i<3; i++)
{
ptr=alf.find(ch[i]);
if ( ptr!=alf.end() )
cl[i]=(ptr->second);
Out<<cl[i];
}
}
In.close();
Out.close();
switch (message)
{
case WM_COMMAND:
switch (wParam)
{
case IDOK:
EndDialog(hDlg,TRUE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return FALSE;
}
LRESULT CALLBACK DESHIFR_HILA(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int i, j, d=0, x=0;
int key_1[3][3];
int ch[3];
char cl[3];
char file1[20]="D:\\deshifr.txt";
char file2[20]="D:\\shifr2.txt";
map<int, char> alf;
map<char, int> alf2;
map<int, char> :: iterator ptr;
map<char, int> :: iterator ptr2;
Ifstream In;
ofstream Out;
//определение нашего алфавита
for (i=0; i<26; i++)
{
alf.insert(pair<int, char> (i, i+65));
alf2.insert(pair<char, int> (i+65, i));
}
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
key_1[i][j]= pow((double)-1, (double)i+j)*(key[(j+1)%3][(i+1)%3]*key[(j+2)%3] [(i+2)%3]-key[(j+1)%3][(i+2)%3]*key[(j+2)%3][(i+1)%3]);
key_1[i][j]*=pow((double)-1, (double)i+j);
}
}
d=(key[0][0]*key[1][1]*key[2][2]+key[1][0]*key[2][1]*key[0][2]+key[0][1]*key[1][2]*key[2][0])-(key[2][0]*key[0][2]*key[1][1]+key[1][0]*key[0][1]*key[2][2]+key[0][0]*key[2][1]*key[1][2]);
while((d*x)%26!=1 && x!=26)
x++;
//Нахождение ключа для расшифровки
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
key_1[i][j]*=x;
while (key_1[i][j]<0)
key_1[i][j]=26+key_1[i][j];
key_1[i][j]%=26;
}
}
In.Open(file1);
Out.open(file2);
//Расшифровка сообщения
while(!In.eof())
{
for (i=0; i<3; i++)
{
In>>cl[i];
if(In.eof())
{
j=0;
while(j!=i)
{
Out<<cl[j];
j++;
}
break;
}
}
if(In.eof())
break;
for(i=0; i<3; i++)
{
ptr2=alf2.find(cl[i]);
if ( ptr2!=alf2.end() )
cl[i]=(ptr2->second);
}
for(i=0; i<3; i++)
{
ch[i]=0;
for(j=0; j<3; j++)
{
ch[i]+=cl[j]*key_1[i][j];
}
}
for(i=0; i<3; i++)
ch[i]=ch[i]%26;
for(i=0; i<3; i++)
{
ptr=alf.find(ch[i]);
if ( ptr!=alf.end() )
cl[i]=(ptr->second);
Out<<cl[i];
}
}
In.Close();
Out.close();
switch (message)
{
case WM_COMMAND:
switch (wParam)
{
case IDOK:
EndDialog(hDlg,TRUE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return FALSE;
}
int INDEX(const char *X, char *A)
{
int i,j,k=0;
char *B="J", s[50];
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
s[0]=A[5*i+j];
s[1]='\0';
if(strcmp(X,s)==0)
return (10*i+j);
}
}
if(strcmp(X,B)==0)
return 21;
return 0;
}
LRESULT CALLBACK PLEYFER(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int i=0, j=0, dlina=0, K1=0, K2=0, x=0 ;
char A[100]= "HARPSICODBEFGKLMNQTUVWXYZ", *S="X", Z[50], *ptr, TEXT[100] ;
char file1[20]="D:\\shifr.txt";
char file2[20]="D:\\deshifr.txt";
Ifstream In;
ofstream Out;
In.Open(file1);
Out.open(file2);
while(!In.eof())
{
In>>TEXT[i];
i++;
}
TEXT[i-1]='\0';
dlina=strlen(TEXT);
//Проверка на повторяющиеся элементы
for(i=0;i<dlina;i++)
{
if(TEXT[i]==TEXT[i+1])
{ x++;
for(j=dlina+x;j>i;j--)
TEXT[j]=TEXT[j-1];
TEXT[dlina+x+1]='\0';
TEXT[i+1]='X';
}
}
dlina=strlen(TEXT);
ptr=&TEXT[0];
//Проверка на четное количество букв
if((dlina%2)!=0)
{
strcat(ptr,S);
strcpy(TEXT,ptr);
dlina=strlen(TEXT);
}
i=0;
while(i!=dlina)
{
Z[0]=TEXT[i];
Z[1]='\0';
K1=INDEX(Z,A) ;
Z[0]=TEXT[i+1];
Z[1]='\0';
K2=INDEX(Z,A) ;
//Находится в одной строке
if(K1/10==K2/10)
{ if((K1%10)==4)
{
TEXT[i]=A[(K1/10)*5];
TEXT[i+1]=A[(K2/10)*5+(K2%10)+1];
}
else
{ if((K2%10)==4)
{ TEXT[i]=A[(K1/10)*5+(K1%10)+1];
TEXT[i+1]=A[(K2/10)*5];
}
else
{ TEXT[i]=A[(K1/10)*5+(K1%10)+1];
TEXT[i+1]=A[(K2/10)*5+(K2%10)+1];
}
}
}
else
{ //Находится в одном столбце
if(K1%10==K2%10)
{ if((K1/10)==4)
{
TEXT[i]=A[(K1%10)];
TEXT[i+1]=A[(K2%10)+(K2/10)*5+5];
}
else
{ if((K2/10)==4)
{
TEXT[i]=A[(K1/10)*5+(K1%10)+5];
TEXT[i+1]=A[(K2%10)];
}
else
{
TEXT[i]=A[(K1%10)+(K1/10)*5+5];
TEXT[i+1]=A[(K2%10)+(K2/10)*5+5];
}
}
}
else
{ if((K1/10)<(K2/10))
{ TEXT[i]=A[(K1/10)*5+(K2%10)];
TEXT[i+1]=A[(K2/10)*5+(K1%10)];
}
else
{
TEXT[i+1]=A[(K2/10)*5+(K1%10)];
TEXT[i]=A[(K1/10)*5+(K2%10)];
}
}
}
i=i+2;
}
for(i=0;i<dlina;i++)
{
Out<<TEXT[i];
}