Ferramentas de Usuário

Ferramentas de Site


dev_geral:c:cifra_de_caesar

Cifra de César

Contexto Histórico

A Cifra de César (em inglês Caesar cipher), era utilizada por Júlio César, imperador romano, com o fim a transmitir mensagens militares seguras. Embora muito rudimentar (esta consiste na rotação de inicialmente três posições, pois mais tarde poderiam mais ou menos, sendo apenas que tanto o receptor, como o emissor tinham que utilizar o mesmo número), esta deveria surtir bastante efeito, quer porque os poucos dos seus inimigos eram alfabetizados, quer porque não se dedicavam à criptoanálise. Para mais informações sobre a cifra de César ver Caesar_Chiper.

Cifrar

Exemplo da implementação da Cifra de César (para uma palavara com um máximo de 100 caracteres):

#define MAX 101
#include "stdio.h"
/**
 * Caesar cipher.
 * Encrypt function.
 *
 * @param n key (0<=n<=25).
 * @param plain text to encrypt.
 * @param crypt encrypted text (cryptogram).
 *
 * @retrun size of plain.
 */
int encrypt(int n, char* plain, char* crypt)
{
  int i;
 
  for(i=0; plain[i]!='0'; i++)
  {
    if(plain[i]>='a' && plain[i]<='z')
      crypt[i]=(plain[i]-'a'+n+26) % 26 + 'a';
    else if(plain[i]>='A' && plain[i]<='Z')
      crypt[i]=(plain[i]-'A'+n+26) % 26 + 'A';
    else
      crypt[i]=plain[i];
  }
 
  crypt[i]='0';
 
  return i;
}
 
int main(){
    int numero;
    char texto[MAX], cifrado[MAX];
    printf("Introduza a palavra a cifrar: ");
    scanf("%s", texto);
    do{
       printf("Introduza o número de casas: "); 
       scanf("%d", &numero);
    } while (numero > 26 || numero < 1);
    encrypt(numero,texto,cifrado);
    printf("%s", cifrado);
}

Se colocarmos: portugalaprogramar como palavra a cifrar e 6 no número de casas obtemos a nossa palavra cifrada: vuxzamgrgvxumxgsgx

Decifrar

E para decifrar(atenção que o número de casas terá que ser igual a quando foi encripitado):

#define MAX 101
#include "stdio.h"
/**
 * Caesar cipher.
 * Decrypt function.
 *
 * @param n the key (0<=n<=25).
 * @param crypt text to decrypt.
 * @param plain decrypted text.
 *
 * @return size of crypt.
 */
 
 int decrypt(int n, char* crypt, char* plain)
{
  int i;
 
  for(i=0; crypt[i]!='0'; i++)
  {
    if(crypt[i]>='a' && crypt[i]<='z')
      plain[i]=(crypt[i]-'a'-n+26) % 26 + 'a';
    else if(crypt[i]>='A' && crypt[i]<='Z')
      plain[i]=(crypt[i]-'A'-n+26) % 26 + 'A';
    else
      plain[i]=crypt[i];
  }
 
  plain[i]='0';
 
  return i;
}
 
int main(){
    int numero;
    char texto[MAX], cifrado[MAX];
    printf("Introduza a palavra cifrada: ");
    scanf("%s", cifrado);
    do{
       printf("Introduza o número de casas: "); 
       scanf("%d", &numero);
    } while (numero > 26 || numero < 1);
    decrypt(numero,cifrado,texto);
    printf("%s", texto);
}

Se fornecemos aqui a palavra cifrada anteriormente e o número de casas (6), ele devolve-nos portugalaprogramar, ou seja a palavra que tínhamos cifrado

A verdadeira fragilidade

O número de casas já aumenta a segurança, no entanto esta pode facilmente ser quebrada com o exemplo de cima, mas alterando a função principal, de modo a não ser necessário introduzis o número de casas:

#include "stdio.h"
int main(){
	int register i;
	int numero;
	char texto[MAX], cifrado[MAX];
	printf("Introduza a palavra cifrada: ");
    scanf("%s", cifrado);
	for (i = 1; i <= 26; i++){
		decrypt(i,cifrado,texto);
		printf("%d: %sn", i, texto);
	}
}

Se aqui introduzirmos simplesmente a palavra cifrada, vuxzamgrgvxumxgsgx e mais nada, ele retornará várias hipóteses:

  • 1: utwyzlfqfuwtlwfrfw
  • 2: tsvxykepetvskveqev
  • 3: sruwxjdodsurjudpdu
  • 4: rqtvwicncrtqitcoct
  • 5: qpsuvhbmbqsphsbnbs
  • 6: portugalaprogramar
  • 7: onqstfzkzoqnfqzlzq
  • 8: nmprseyjynpmepykyp
  • 9: mloqrdxixmoldoxjxo
  • 10: lknpqcwhwlnkcnwiwn
  • 11: kjmopbvgvkmjbmvhvm
  • 12: jilnoaufujlialugul
  • 13: ihkmnztetikhzktftk
  • 14: hgjlmysdshjgyjsesj
  • 15: gfiklxrcrgifxirdri
  • 16: fehjkwqbqfhewhqcqh
  • 17: edgijvpapegdvgpbpg
  • 18: dcfhiuozodfcufoaof
  • 19: cbeghtnyncebtenzne
  • 20: badfgsmxmbdasdmymd
  • 21: azcefrlwlaczrclxlc
  • 22: zybdeqkvkzbyqbkwkb
  • 23: yxacdpjujyaxpajvja
  • 24: xwzbcoitixzwoziuiz
  • 25: wvyabnhshwyvnyhthy
  • 26: vuxzamgrgvxumxgsgx

De onde se percebe facilmente que a única palavra aceitável é portugalaprogramar

Atenção! Esta cifra, como podemos constatar é muito frágil, e não é aconselhável para guardar dados sensíveis, pois esta serve agora essencialmente para fins académicos
dev_geral/c/cifra_de_caesar.txt · Última modificação em: 2018/05/14 21:37 (edição externa)