[C] La crittografia ai tempi di Cesare

Creato il 16 aprile 2012 da Ketek @CarloVentrella

Inauguriamo questa sezione con uno dei più antichi algoritmi di crittografia: il cifrario di Cesare.

Il cifrario, che prende il nome da Giulio Cesare, venne utilizzato dallo stesso per proteggere i messaggi segreti e,nonostante la sua semplicità, non fu mai compreso dai suoi nemici grazie, in particolar modo, all'ignoranza dei soldati.

Il meccanismo di funzionamento del cifrario si basa sullo "scivolamento" di una lettera di un numero di posti corrispondente al valore della chiave utilizzata, che più fonti attribuiscono a 3.

Dunque se utlilizziamo la chiave 3 la parola abc (che fantasia!) diventerebbe def perchè:

a + 3 -> d

b + 3 -> e

f + 3 -> f

Vediamo come sviluppare l'algoritmo del cifrario di Cesare che ci permetta tuttavia di utilizzare una chiave a scelta utilizzando il linguaggio C:

#include <stdio.h>

#include <windows.h>

#include <stdlib.h>

#include <conio.h>

void SetColor(short Color)

{

HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleTextAttribute(hCon,Color);

}

int main (int argc, const char * argv []) {

int i,y=0,valore_ascii;

char parola[25] ;

char n, psw=0;

SetColor(4);

printf (" *.*.*.*.*.*.___IL CIFRARIO DI CESARE___.*.*.*.*.*.*");

SetColor(15);

printf ("Inserire in ordine sequenziale le lettere della parola da criptare.");

printf("Inserire il numero delle lettere di cui ogni lettera deve spostarsi: ");

SetColor(4);

scanf ("%d", &i);

SetColor(15);

if (i < 0 || i > 26)

{

printf("Niente valori negativi o maggiori di 26");

exit(1);

}

printf ("Ogni lettera si spostera' di %d posti", i);

printf ("Inserisci la parola da criptare: ");

SetColor(4);

scanf("%s", &parola);

SetColor(15);

printf("new password: ");

SetColor(10);

for (n=0; parola[n] != '�'; n++){

y=0;

valore_ascii = (int)parola[n];

if (valore_ascii >= 65 & valore_ascii <= 90)

{

// è una lettera maiuscola

if (valore_ascii + i > 90)

{

y = valore_ascii + i - 26;

}

}

else if (valore_ascii >= 97 & valore_ascii <=122)

{

// è una lettera maiuscola

if (valore_ascii + i >122)

{

y = valore_ascii + i - 26;

}

}

if (y == 0){ // altrimenti (se non è stato toccato) non cambio nulla

y = valore_ascii + i;

}

char z=0;

z = (char)y;

printf("%c", z);

}

SetColor(15);

printf("Crittografia completata.");

printf("");

return 1;

}

Copia tutto

Dopo l'inserimento della chiave e della parola da crittografare quest' ultima viene "scomposta" e i suoi caratteri inseriti in un array;

Ora converto i singoli caratteri in variabili numeriche che corrisponderanno al valore in ASCII della lettera in questione.

Addiziono i valori ottenuti alla chiave e ritrasformo il valore in carattere.

Quindi questo è quello che succederà alla lettera 'a' (e non 'A' a cui corrisponde un altro valore):

a -> 97

97 + 3 -> 100

100 -> c

Ci tengo a precisare la funzione dei due controlli:

if (valore_ascii >= 65 & valore_ascii <= 90)

...

else if (valore_ascii >= 97 & valore_ascii <=122)

Copia tutto

Se la chiave fosse 3 e la lettera della parola fosse 'z' otterremmo il carattere speciale '}' e non quello che vorremmo ('c') : con questi e due cicli controllo prima se la lettera è maiuscola (compresa tra 65 e 90) o minuscola (compresa tra 97 e 122) e in seguito controllo che la somma tra il valore della lettera e la chiave non esca fuori dal "margine"(90 o 122). In caso contrario sottrarrò alla somma 26, che corrisponde alle lettere totali in modo da far ricominciare da 'a' o 'A'.