Logo Hardware.com.br
D3V1LL3
D3V1LL3 Super Participante Registrado
667 Mensagens 25 Curtidas

Cifra de Cesar - Código em C

#1 Por D3V1LL3 03/04/2013 - 15:12
E ai pessoal,

Eu estava lendo o tópico sobre POG e gostaria que avaliassem esse código. É a segunda vez que uso ponteiro e não tenho costume de programar em C...Mas retomando uma vontade antiga de colaborar com o desenvolvimento de alguma distro Gnu/linux, estou tentando aprender C em um nivel intermediario (ainda estou no básico).:

Fonte do desáfio:http://pt.wikipedia.org/wiki/Cifra_de_C%C3%A9sar


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

void limpar()
{
system ("clear || cls&quot;
}

char cifrar(char *texto, int chave)
{
int tam=strlen(texto); /*Pega o tamanho do texto passado*/
int i=0,x=0,cont=0; /*Variaveis auxiliares*/
char letra;

/*Zerando variaveis para reutilizar....*/
cont=0;
x=0;
i=0;

/*Loop para verificar se uma letra do alfabeto existe no texto. A cada ocorrencia, substitui essa letra
de acordo com o deslocamento passado por parametro.*/
for (letra='a'; letra<='z'; letra++)
{
while(i<=tam)
{
if(texto[i] == letra)
{
texto[i]=letra+chave;
i++;
cont ++;
letra='a';
}
else if(texto[i] == ' ')
{
i++;
cont ++;
letra='a';
}
else if(texto[i] == toupper(letra))
{
texto[i]=toupper(letra+chave);
i++;
cont ++;
letra='a';
}
else
{
letra++;
}
if(cont == tam)
break;
}
}
limpar();
return printf("\n\n\t\tCodigo Gerado: %s\n",texto);
}

char decifrar(char *codigo,int chave)
{
int tam=strlen(codigo); /*Pega o tamanho do texto passado*/
int i=0,x=0,cont=0; /*Variaveis auxiliares*/
char alfa[52],letra; /*vetor com alfabeto*/
limpar();
printf("\n\t\t Decifrando o codigo %s.......\n",codigo);
for (letra='a'; letra<='z'; letra++)
{
while(i<=tam)
{
if(codigo[i] == letra)
{
codigo[i]=letra-chave;
i++;
cont ++;
letra='a';
}
else if(codigo[i] == ' ')
{
i++;
cont ++;
letra='a';
}
else if(codigo[i] == toupper(letra))
{
codigo[i]=toupper(letra-chave);
i++;
cont ++;
letra='a';
}
else
{
letra++;
}
if(cont == tam)
break;
}
}
return printf("\n\n\t\t Mensagem Decifrada: %s \n",codigo);
}

int main()
{
int op=3,chave=2,i,confirma=0;
char *mensagem,*cifrado;
mensagem = (char *)malloc(100);
cifrado = (char *)malloc(100);
/*Exibe o menu para escolher criptografar ou nao...*/
while (op!=0)
{
printf ("---- Sistema de Criptografia - CifraCesar ----\n&quot;
printf ("\t\t Escolha uma Opcao: \n&quot;
printf ("1-)Criptografar Texto |\n 2-)Decifrar Codigo |\n 0-)Sair &quot;
scanf ("%d",&op);
if(op == 1)
{
printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);

printf ("Mensagem: \n&quot;
fflush(stdin);
gets(mensagem);
printf("A mensagem tem o tamanho de %d caracteres: \n %s",strlen(mensagem),mensagem);
getch();

cifrar(mensagem,chave);
cifrado=mensagem;
confirma=1;
getch();
limpar();
}
else if(op == 2)
{
if(confirma != 1)
{
printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);

printf ("Codigo: \n&quot;
fflush(stdin);
gets(cifrado);
decifrar(cifrado,chave);
getch();
limpar();
}
else
{
printf("Valor do codigo: %s",cifrado);
getch();
decifrar(cifrado,chave);
getch();
limpar();
op=0;
}
}
else if (op == 0)
{
break;
free (mensagem);
free (cifrado);
}


}
}
Obrigado!

[ ]'s
Henry-Keys
Henry-Keys Geek Registrado
1.8K Mensagens 235 Curtidas
#2 Por Henry-Keys
03/04/2013 - 15:23
Salve Devil smile.png


É a primeira vez que ouço falar desta técnica de criptografia, ou melhor, eu já usava antes, mas não sabia o nome. Normalmente acho mais apropriado "escovar bits" para encriptar os bytes (o operador bitwise ^(XOR) é famoso por isso)

Concerteza vou ler o código (ops! já comecei mostrando_lingua.png).
Mas antes gostaria que você resumisse os detalhes do funcionamento do programa.


À primeira vista dá pra ver que o código está bem indentado e pouco POGado.


Abraços.
D3V1LL3
D3V1LL3 Super Participante Registrado
667 Mensagens 25 Curtidas
#4 Por D3V1LL3
03/04/2013 - 15:34
E ai, Henry-Keys!

O codigo funciona meio "torto" ainda...mas é +- assim:

Na primeira execução o usuário passa uma chave de descolamento. Essa chave é usada no metodo de criptografia para definir o processo de substituição.
Ex: Chave 2 - Palavra Teste - Saida T=T+2 posições|e=e+2 posições....
Sendo essas posições a ordem do alfabeto brasileiro.
Saida final: Vguvg

Inicio do programa:
Para as variaveis que receberão a mensagem e o valor cifrado, eu usei ponteiros do tipo char e depois aloco uma memoria X. Eu nao me preocupei em solicitar o tamanho do texto para o usuário porque ainda é experimental essa ideia de alocar memoria com malloc e etc... (primeira vez nesse caso).

Metodo para cifrar/decifrar:
recebe como parametro o texto e a chave de deslocamento;
usando 2 loops o programa verifica se uma letra existe no texto. Caso exista, o programa usa a chave de deslocamento para definir a letra que substui a atual no texto.
O metodo para decifrar é bem parecido, na verdade um control-cola mesmo...O que muda é que eu não avanço na substituição (a=c), mas eu uso a chave de deslocamento como substração(c=a).

Conseguiu entender um pouco?

[ ]'s
"Aprendiz Emergente"
D3V1LL3
D3V1LL3 Super Participante Registrado
667 Mensagens 25 Curtidas
#5 Por D3V1LL3
03/04/2013 - 15:37
Fergo disse:
Não analisei todo o código, mas vi que você criou uma função para cifrar e outra para decirar, sendo que esta é desnecessária, basta usar a mesma função de cifrar com a chave invertida.

Eu não pensei em outro metodo para decifrar, mas a ideia era usar um metodo diferente para variar nos algoritmos...

Do jeito que está eu concordo que até mesmo uma variavel char "tipo" com algo como:

/*tipo = + <- cifrar | tipo = - <- decifrar*/
char tipo='+';

E então usaria apenas uma função....

[ ]'s
"Aprendiz Emergente"
Henry-Keys
Henry-Keys Geek Registrado
1.8K Mensagens 235 Curtidas
#6 Por Henry-Keys
03/04/2013 - 15:47
Já testei, e tá meio torto mesmo.

Fiz um port para Linux e outros (conio.h frown.png ):

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


#ifdef WIN32
#include <conio.h>

#else
#define getch(a) getchar(a); fflush(stdin)
#endif


void limpar()
{
system ("clear || cls&quot;
}


char cifrar(char *texto, int chave)
{
int tam=strlen(texto); /*Pega o tamanho do texto passado*/
int i=0,x=0,cont=0; /*Variaveis auxiliares*/
char letra;


/*Zerando variaveis para reutilizar....*/
cont=0;
x=0;
i=0;

/*Loop para verificar se uma letra do alfabeto existe no texto. A cada ocorrencia, substitui essa letra
de acordo com o deslocamento passado por parametro.*/
for (letra='a'; letra<='z'; letra++)
{
while(i<=tam)
{
if(texto[i] == letra)
{
texto[i]=letra+chave;
i++;
cont ++;
letra='a';
}
else if(texto[i] == ' ')
{
i++;
cont ++;
letra='a';
}
else if(texto[i] == toupper(letra))
{
texto[i]=toupper(letra+chave);
i++;
cont ++;
letra='a';
}
else
{
letra++;
}
if(cont == tam)
break;
}
}
limpar();
return printf("\n\n\t\tCodigo Gerado: %s\n",texto);
}


char decifrar(char *codigo,int chave)
{
int tam=strlen(codigo); /*Pega o tamanho do texto passado*/
int i=0,x=0,cont=0; /*Variaveis auxiliares*/
char alfa[52],letra; /*vetor com alfabeto*/
limpar();
printf("\n\t\t Decifrando o codigo %s.......\n",codigo);
for (letra='a'; letra<='z'; letra++)
{
while(i<=tam)
{
if(codigo[i] == letra)
{
codigo[i]=letra-chave;
i++;
cont ++;
letra='a';
}
else if(codigo[i] == ' ')
{
i++;
cont ++;
letra='a';
}
else if(codigo[i] == toupper(letra))
{
codigo[i]=toupper(letra-chave);
i++;
cont ++;
letra='a';
}
else
{
letra++;
}
if(cont == tam)
break;
}
}
return printf("\n\n\t\t Mensagem Decifrada: %s \n",codigo);
}


int main()
{
int op=3,chave=2,i,confirma=0;
char *mensagem,*cifrado;
mensagem = (char *)malloc(100);
cifrado = (char *)malloc(100);
/*Exibe o menu para escolher criptografar ou nao...*/
while (op!=0)
{
printf ("---- Sistema de Criptografia - CifraCesar ----\n&quot;
printf ("\t\t Escolha uma Opcao: \n&quot;
printf ("1-)Criptografar Texto |\n 2-)Decifrar Codigo |\n 0-)Sair &quot;
scanf ("%d",&op);
if(op == 1)
{
printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);


printf ("Mensagem: \n&quot;
fflush(stdin);
gets(mensagem);
printf("A mensagem tem o tamanho de %d caracteres: \n %s",strlen(mensagem),mensagem);
getch();


cifrar(mensagem,chave);
cifrado=mensagem;
confirma=1;
getch();
limpar();
}
else if(op == 2)
{
if(confirma != 1)
{
printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);


printf ("Codigo: \n&quot;
fflush(stdin);
gets(cifrado);
decifrar(cifrado,chave);
getch();
limpar();
}
else
{
printf("Valor do codigo: %s",cifrado);
getch();
decifrar(cifrado,chave);
getch();
limpar();
op=0;
}
}
else if (op == 0)
{
break;
free (mensagem);
free (cifrado);
}




}
}




- Você declarou muitas variáveis inúteis (que não chegaram à ser usadas);


- Não dá para encriptar uma string pequena (p/ exemplo de 3 caracteres), o programa exibe denovo as opções.


- E você fez muito POG (mas muuuitoooo mesmo)


- O que mais odiei, foi o getchar(), não funfa aqui!! (por isso fiz o port).


- Código muito junto (isso dá uma certa ilegibilidade), olha aqui por exemplo:

int tam=strlen(codigo); /*Pega o tamanho do texto passado*/
int i=0,x=0,cont=0; /*Variaveis auxiliares*/
char alfa[52],letra; /*vetor com alfabeto*/
limpar();
printf("\n\t\t Decifrando o codigo %s.......\n",codigo);
for (letra='a'; letra<='z'; letra++)




O que eu gostei


- O loop inteligente que percorre uma string e substitui "soma" os caracteres, gostei do uso do toupper() para obter o maiúsculo (apesar de ter sido um POG).


Dê algumas melhoradas amigo.


Abraços.
D3V1LL3
D3V1LL3 Super Participante Registrado
667 Mensagens 25 Curtidas
#7 Por D3V1LL3
04/04/2013 - 12:05
Boa tarde,

Henry, vou usar o seu port =)


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


#ifdef WIN32
#include <conio.h>

#else
#define getch(a) getchar(a); fflush(stdin)
#endif
Segue o codigo na versão 0.2:

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

/*Colaboracao Henry-Keys =)*/
#include <ctype.h>

#ifdef WIN32
#include <conio.h>

#else
#define getch(a) getchar(a); fflush(stdin)
#endif
/*-------------------------*/


/*Definindo um tipo booleano no braço ;D*/
enum booleano
{
true = 1, false = 0
};
typedef enum booleano BOOL;
/*--------------------------------------*/


/*procedimento para limpar a tela...reaproveitando codigo*/
void limpar()
{
system ("clear || cls&quot;
}
/*-------------------------------------------------------*/


/*Funcao que faz substituicao de cada letra no texto de acordo com a chave numerica informada*/
char cifraCesar(char *texto, int chave, int tipo) // tipo = 0 -> cifrar| tipo = 1 -> decifrar
{
/*-----VARIAVEIS PRINCIPAIS--------*/
int tam=strlen(texto);
int i=0;
int cont=0;
char letra;
char saida[100];
/*----------------------------------*/


/*----------LOOP PARA SUBSTITUIÇÃO---------*/
for (letra='a'; letra<='z'; letra++)
{
while(i<=tam)
{
if(texto[i] == letra)
{
if(tipo == 0)
texto[i] = letra+chave;

else

if (tipo == 1)
texto[i] = letra-chave;

i++;
cont ++;
letra='a';

}

else if(texto[i] == ' ')
{
i++;
cont ++;
letra='a';
}

else if(texto[i] == toupper(letra))
{

if(tipo == 0)
texto[i] = toupper(letra+chave);
else if (tipo == 1)
texto[i] = toupper(letra-chave);

i++;
cont ++;
letra='a';
}

else
letra++;

if(cont == tam)
break;

}
}
/*-----------------------------------------*/

if(tipo == 0)
return printf("Codigo gerado: %s\n",texto);
else
return printf("Mensagem decifrada: %s\n",texto);
}
/*-------------------------------------------------------------------------------------------*/


int main()
{
/*-----VARIAVEIS PRINCIPAIS--------*/
int op=3;
int chave;
char *mensagem;
const int tamanho = 100;
BOOL confirma=false;
/*----------------------------------*/

/*Alocando memoria para receber mensagem (texto puro) e cifrado (texto criptografado)*/
mensagem = (char *)malloc(tamanho);
/*-----------------------------------------------------------------------------------*/

printf ("\n--------------------------------------------\n&quot;
printf ("\n-- Sistema de Criptografia - CifraCesar --\n&quot;
printf ("\n--------------------------------------------\n&quot;

while (op!=0)
{

printf ("\t\t Escolha uma Opcao: \n\n&quot;

printf ("1-)Criptografar Texto \n&quot;
printf ("2-)Decifrar Codigo \n&quot;
printf ("0-)Sair \n&quot;
scanf ("%d",&op);

if (op == 1)
{

printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);

printf ("Mensagem: \n&quot;
fflush(stdin);
gets(mensagem);

cifraCesar(mensagem,chave,0);

getch();

confirma=true;
limpar();
}

else if (op == 2)
{

if (confirma == false)
{

printf("Chave de Deslocamento: &quot;
scanf ("%d",&chave);

printf ("Mensagem: \n&quot;
fflush(stdin);
gets(mensagem);

cifraCesar(mensagem,chave,1);
getch();

limpar();
}

else if(confirma == true)
{

cifraCesar(mensagem,chave,1);
getch();

limpar();
op=0;
}
}
else if (op == 0)
{
free(mensagem);
break;
}

else
{

printf("\n\t Verifique a Opcao escolhida!\n&quot;
getch();

limpar();
break;
}


}

}


1-) Acho que consegui melhorar...

- Você declarou muitas variáveis inúteis (que não chegaram à ser usadas)
2-) Testei aqui e funcionou...

- Não dá para encriptar uma string pequena (p/ exemplo de 3 caracteres), o programa exibe denovo as opções.
3-)Ainda tem, mas acho que melhorou...

- E você fez muito POG (mas muuuitoooo mesmo)
4-)Nao gosto de deixar muito separado, mas também tentei separar...


- Código muito junto (isso dá uma certa ilegibilidade), olha aqui por exemplo:
Ainda vou testar outros algoritmos... eu preciso estudar o realloc para controlar um texto grande...

Obrigado!

[ ]'s
"Aprendiz Emergente"
D3V1LL3
D3V1LL3 Super Participante Registrado
667 Mensagens 25 Curtidas
#9 Por D3V1LL3
04/04/2013 - 13:56
Henry-Keys disse:
Realmente melhorou (e muito), fiquei impressionando.

Mas aqui, alguns bugs persistem frown.png


Experimente crifrar uma só letra ou duas!!
Quando você cifra uma palavra e na próxima tenta decifrar qualquer outro o programa fecha.
Por vezes o programa não cifra todos os caracteres.


Do resto está tudo muito bom!! smile.png


Abraços.

Aqui funcionou com apenas uma letra....
A ideia é o programa permitir cifrar 1 vez e decifrar o mesmo código ou se você escolher direito a opção decifrar, o programa permite que você entre com o código...

Será que já posso postar esse código no tópico de códigos do djJoe?
Vou postar alguns para avaliação e os otimizados eu posto lá =]

[ ]'s
"Aprendiz Emergente"
ripongao
ripongao Veterano Registrado
755 Mensagens 94 Curtidas
#12 Por ripongao
04/04/2013 - 15:42
o site da "vóvó vick" é um excelente lugar para começar a ler e aprofundar-se sobre, foi lá que me iniciei, e o interessante é que a autora recorre a fatos históricos, ... , ela inclusive lançou um livro.
A cifra de César (dái a Cesar o que é de Cesar) roda o alfabeto (conjunto de símbolos) em X casas para a esquerda, para decifrar é necessário rodar o alfabeto X casas para a direita, matematicamente falando isso significa adicionar para cifrar e subtrair para decifrar, partindo do ponto inicial (a letra A). Uma cobra tentando comer o próprio rabo, uma forma de anel rotativo.
http://www.numaboa.com.br/criptografia

Para os que apreciam informática, frequentava o site abaixo durante outrora.
http://3564020356.org/
dica: "Não olhe, veja"
dica2: não entre no site se logado em algum fórum/rede social ou algo parecido. Não que exista má fé ou o link seja impróprio, apenas questão de segurança.
Desliguei-me do fórum. Conta canelada.
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal