/* Trabalho de Matemática Discreta
Criptografia de HILL: Elaborar uma criptografia e descodificar o código gerado.
Felipe Barbosa Pereira
Kimberly Lima
Rodrigo Pontes
Ciência da Computação
10/11/2015
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
void tira_espaco(char *);
void menu(void);
void menu_2(char *);
void titulo (void);
void adiciona_letra(char *);
void mudar_para_criptografia(char *, int *);
void criptografiaHill(int *, int [2][2], int, char *);
void pega_codigo(int [2][2]);
int verifica_codigo(int[2][2]);
void descodificar(int, int[2][2], char *, int, int *);
void sugestao(int [2][2]);
int main ()
{
char str[501];
int str_2[500];
int determinante_inversa;
int cod[2][2];
char c;
int k;
char opcao;
menu();
do
{
{
case '1':
titulo();
printf("Entre com a palavra ou frase a ser criptografada por cifras de HILL:\n"); scanf("%499[^\n]s", str
);
tira_espaco(str);
do
//Loop para receber os codigos até que um deles seja validado
{
pega_codigo(cod);
determinante_inversa = verifica_codigo(cod);
if (cod[0][0]*cod[1][1] - cod[0][1]*cod [1][0] == 0)
//Se determinante for 0, essa matriz é invalida
{
printf ("\n\nO codigo informado não está correto, pois não é inversível!\nEntre com outro código!\n"); }
if (determinante_inversa == 69)
// essa variavel recebeu um numero pela função verifica_codigo, esse numero é devido que a determinante inversa não está em modulo 26
{
printf("\n\nO codigo informado não está correto!\nA determinante inversa não está em modulo 26!\nEntre com outro código!\n\n\n"); sugestao(cod);
_sleep(3000);
}
}
while (determinante_inversa == 69);
//Verifico se for impar, chama função de repetir a ultima letra
{
adiciona_letra(str);
}
mudar_para_criptografia(str, str_2);
//Entra com a string e muda a string informada para os numeros da cifra em str_2
criptografiaHill(str_2, cod, k, str);
printf("\n\nPalavra criptografada por HILL: %s\n\n\n", str
); printf("\n\n\nDigite qualquer tecla para continuar....");
menu_2(str);
menu();
break;
case '2':
titulo();
printf("Entre com a palavra ou frase a ser decodificada por cifras de HILL:\n"); scanf("%499[^\n]s", str
);
tira_espaco(str);
int cod[2][2];
do
{
pega_codigo(cod);
determinante_inversa = verifica_codigo(cod);
if (cod[0][0]*cod[1][1] - cod[0][1]*cod [1][0] == 0)
{
printf ("\n\nO codigo informado não está correto, pois não é inversível!\nEntre com outro código!\n\n\n"); }
if (determinante_inversa == 69)
{
printf("\n\nO codigo informado não está correto!\nA determinante inversa não está em modulo 26!\nEntre com outro código!\n\n\n"); _sleep(3000);
}
}
while (determinante_inversa == 69);
//printf("Determinante inversa: %d", determinante_inversa);
{
adiciona_letra(str);
}
mudar_para_criptografia(str, str_2);
descodificar(determinante_inversa, cod, str, k, str_2);
printf("\n\n\t\tDecodificação efetuada com sucesso!\n\n'%s'\n\n\n\n", str
);
printf("\n\n\nDigite qualquer tecla para continuar....");
menu();
}
}
while (c != 27);
return 0;
}
void menu ()
{
printf("\n--------------------------------------------------------------------------------\n\tBem vindo ao programa de CRIPTOGRAFIA CIFRAS DE HILL\n\n--------------------------------------------------------------------------------\n\n"); printf("\t\t\t*--------------------------*\n"); //26 espaços printf("\t\t\t|ESCOLHA A OPÇÃO PRETENDIDA|\n\t\t\t| |\n"); printf("\t\t\t|1 - Codificar |\n\t\t\t| |\n\t\t\t|2 - Decodificar |\n"); printf("\t\t\t*--------------------------*\n\n"); }
void menu_2 (char *str)
{
printf("\n--------------------------------------------------------------------------------\n\tBem vindo ao programa de CRIPTOGRAFIA CIFRAS DE HILL\n\n--------------------------------------------------------------------------------\n\n"); printf("\n\nDESEJA SALVAR A PALAVRA CRIPTOGRAFADA EM UM ARQUIVO?\n\n'S' para SIM ou 'N' para NÃO\n\n");
char opcao;
if (opcao == 's' || opcao == 'S')
{
FILE *pa;
pa
= fopen("Criptografia_de_HILL.txt", "w"); fprintf(pa
, "--------------------------------------------------------------------------------\n\tBem vindo ao programa de CRIPTOGRAFIA CIFRAS DE HILL\n\n--------------------------------------------------------------------------------\n\n"); fprintf(pa
, "\n\nTexto Criptografado ''%s'' \n\n\n", str
); fprintf(pa
, "Caso queira colar este texto no programa siga os passos:\n\n1º - Copie o texto\nObs: NÃO COPIE AS ASPAS!\n\n"); fprintf(pa
, "2º - Abra o menu do programa 'Decodificar'\n\n3º - Na Barra de Título, clique com o botão direito do mouse -> Editar -> Colar\n\n\n\nLembre-se de fechar este documento caso queira salvar outra criptografia!"); fprintf(pa
, "\n\n\n\n\n********************************************************************************\n\n\t\t\tPrograma desenvolvido por:\n\n\t\t\tFelipe Barbosa\n\t\t\tKimberly Lima\n\t\t\tRodrigo Pontes\n\n\n********************************************************************************\n\nCiência da Computação\n10/11/2015\nUNISANTOS\n\n");
printf("\n\n\nARQUIVO 'Criptografia_de_HILL.txt' GERADO COM SUCESSO!\n\n\n"); printf("Verifique este arquivo na pasta onde o programa está gravado!\n\n\n");
printf("\n\n\nDigite qualquer tecla para continuar....");
}
else
{
}
}
void titulo (void)
{
printf("\n--------------------------------------------------------------------------------\n\tBem vindo ao programa de CRIPTOGRAFIA CIFRAS DE HILL\n\n--------------------------------------------------------------------------------\n\n"); }
void tira_espaco(char *str)
{
char aux;
for (l = 0 ; l < k ; l++)
{
for (i = 0 ; i < k ; i++)
{
if (str[i] == ' ')
{
for (j = i; j < k ; j++)
{
aux = str[j+1];
str[j] = aux;
}
}
}
}
}
void adiciona_letra(char *str)
{
char letra
= str
[strlen(str
)-1]; str[aux+1] = '\0';
}
void mudar_para_criptografia(char *str, int *str_2)
//Recebo a string informada pelo usuário e modifico essa string para os numeros da cifra de HILL na variável inteira str_2
{
int i, j = 0;
for (i
= 0 ; i
< strlen(str
) ; i
++) {
if (str[i] > 64 && str[i] < 91)
{
str_2[j] = str[i] - 64;
}
else if (str[i] > 96 && str[i] < 123)
{
str_2[j] = str[i] - 96;
}
if (str_2[j] == 26)
{
str_2[j] = 0;
}
j++;
}
}
void criptografiaHill(int *str_2, int cod[2][2], int k, char *str)
{
int j = 0, i;
int str_HILL[500];
for (i = 0 ; i < k/2 ; i ++)
{
str_HILL[j] = (cod[0][0] * str_2[j]) + (cod[0][1] * str_2[j+1]);
if (str_HILL[j] > 26 )
{
do
{
str_HILL[j] %= 26;
}
while (str_HILL[j] > 26);
if (str_HILL[j] == 0 )
{
str_HILL[j] = 26;
}
/*if (str_HILL[j] < 0 )
{
str_HILL[j] = (str_HILL[j] % 26) + 26;
}*/
}
else if (str_HILL[j] == 0 )
{
str_HILL[j] = 26;
}
str[j] = str_HILL[j] + 64;
str_HILL[j+1] = (cod[1][0] * str_2[j]) + (cod[1][1] * str_2[j+1]);
if (str_HILL[j+1] > 26)
{
do
{
str_HILL[j+1] %= 26;
}
while (str_HILL[j+1] > 26);
if (str_HILL[j+1] == 0 )
{
str_HILL[j+1] = 26;
}
/* if (str_HILL[j] < 0 )
{
str_HILL[j+1] = (str_HILL[j+1] % 26) + 26;
}*/
}
if (str_HILL[j+1] == 0 )
{
str_HILL[j+1] = 26;
}
str[j+1] = str_HILL[j+1] + 64;
j+=2;
}
str[k] = '\0';
}
void pega_codigo(int cod[2][2])
{
printf("\n\n\tEntre com o código (em linhas) :\n\n1º codigo: ");
int i, j;
/*printf("\n\n\n\t Código informado:\n\n");
for (i = 0; i < 2; i++)
{
for (j = 0 ; j < 2 ; j++)
{
printf("\t %d", cod[i][j]);
}
printf("\n");
}*/
}
int verifica_codigo(int cod[2][2])
{
int determinante = cod[0][0]*cod[1][1] - cod[0][1]*cod[1][0];
int determinante_inversa;
//printf("\n\nDeterminante: %d\n\n", determinante);
/* switch (determinante)
{
case 1:
determinante_inversa = 1;
break;
case 3:
determinante_inversa = 9;
break;
case 5:
determinante_inversa = 21;
break;
case 7:
determinante_inversa = 15;
break;
case 9:
determinante_inversa = 3;
break;
case 11:
determinante_inversa = 19;
break;
case 15:
determinante_inversa = 7;
break;
case 17:
determinante_inversa = 23;
break;
case 19:
determinante_inversa = 11;
break;
case 21:
determinante_inversa = 5;
break;
case 23:
determinante_inversa = 17;
break;
case 25:
determinante_inversa = 25;
break;
default:
printf("Código inválido! Tente novamente!");
determinante_inversa = 69;
break;
}*/
int i;
for (i = 0 ; i < 26 ; i++)
{
if ((determinante*i)%26 == 1)
{
return i;
}
}
return determinante_inversa = 69;
}
void descodificar(int determinante_inversa, int cod[2][2], char *str, int k, int *str_2)
{
int j = 0, i;
int str_HILL[500];
int aux;
aux = cod[0][0] * determinante_inversa;
cod[0][0] = cod[1][1] * determinante_inversa;
cod[1][1] = aux;
cod[0][1] *= determinante_inversa * (-1);
cod[1][0] *= determinante_inversa * (-1);
for (i = 0 ; i < k/2 ; i ++)
{
str_HILL[j] = (cod[0][0] * str_2[j]) + (cod[0][1] * str_2[j+1]);
if (!(str_HILL[j] > 0 && str_HILL[j] < 26))
{
do
{
str_HILL[j] %= 26;
}
while (str_HILL[j] > 26 && str_HILL[j] > -26 );
if (str_HILL[j] == 0 )
{
str_HILL[j] = 26;
}
if (str_HILL[j] < 0 )
{
str_HILL[j] = (str_HILL[j] % 26) + 26;
}
}
str[j] = str_HILL[j] + 64;
str_HILL[j+1] = (cod[1][0] * str_2[j]) + (cod[1][1] * str_2[j+1]);
if (!(str_HILL[j+1] > 0 && str_HILL[j+1] < 26))
{
do
{
str_HILL[j+1] %= 26;
}
while (str_HILL[j+1] > 26 && str_HILL[j+1] > -26 );
if (str_HILL[j+1] == 0 )
{
str_HILL[j+1] = 26;
}
if (str_HILL[j+1] < 0)
{
str_HILL[j+1] = (str_HILL[j+1] % 26) + 26;
}
}
str[j+1] = str_HILL[j+1] + 64;
j+=2;
}
str[k] = '\0';
}
void sugestao(int cod[2][2])
{
int i, j, contador = 0, aux;
int determinante;
int determinante_inversa;
//Verificar para posição 1 do codigo
aux = cod[0][0];
for (j = 1; j <= 5 ; j++)
{
cod[0][0] += j;
determinante = cod[0][0]*cod[1][1] - cod[0][1]*cod[1][0];
for (i = 0 ; i < 26 ; i++)
{
if ((determinante*i)%26 == 1 && contador < 2)
{
if (contador == 0)
{
printf("\n\n\tEscolha uma das alternativas para validação do seu código:\n"); }
printf("\n\nSugerimos que troque o 1º código por: %d\n\n", cod
[0][0]); contador++;
}
}
}
cod[0][0] = aux;
//Verificar para codigo 2:
aux = cod[0][1];
for (j = 1; j <= 5 ; j++)
{
cod[0][1] += j;
determinante = cod[0][0]*cod[1][1] - cod[0][1]*cod[1][0];
for (i = 0 ; i < 5 ; i++)
{
if ((determinante*i)%26 == 1 && contador < 2)
{
if (contador == 0)
{
printf("\n\n\tEscolha uma das alternativas para validação do seu código:\n"); }
printf("\n\nSugerimos que troque o 2º código por: %d\n\n", cod
[0][1]); contador++;
break;
}
}
}
cod[0][1] = aux;
//Verificar para codigo 3:
aux = cod[1][0];
for (j = 1; j <= 5 ; j++)
{
cod[1][0] += j;
determinante = cod[0][0]*cod[1][1] - cod[0][1]*cod[1][0];
for (i = 0 ; i < 26 ; i++)
{
if ((determinante*i)%26 == 1 && contador < 2)
{
if (contador == 0)
{
printf("\n\n\tEscolha uma das alternativas para validação do seu código:\n"); }
printf("\n\nSugerimos que troque o 3º código por: %d\n\n", cod
[1][0]); contador++;
break;
}
}
}
cod[1][0] = aux;
//Verificar para codigo 4:
aux = cod[1][1];
for (j = 1; j <= 5 ; j++)
{
cod[1][1] += j;
determinante = cod[0][0]*cod[1][1] - cod[0][1]*cod[1][0];
for (i = 0 ; i < 26 ; i++)
{
if ((determinante*i)%26 == 1 && contador < 2)
{
if (contador == 0)
{
printf("\n\n\tEscolha uma das alternativas para validação do seu código:\n"); }
printf("\n\nSugerimos que troque o 4º código por: %d\n\n", cod
[1][1]); contador++;
}
}
}
cod[1][1] = aux;
}