Ir para o conteúdo

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 ser facilmente 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: %s\n", 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

Importante: 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