I primi, semplici sistemi di criptazione con esempi di programmazione: il ROT13 e il cifrario di Cesare

Giovanni Bernardo | 21 maggio 2008
Categorie: JavaScript - PHP - Visual Basic

La crittografia è una vera e propria scienza che si occupa di offuscare e rendere apparentemente illeggibile un qualsiasi testo che bisogna tenere nascosto. Le tecniche crittografiche vengono generalmente utilizzate per memorizzare le password o i codici di accesso, che vengono criptati prima di essere salvati, in maniera tale da renderli indecifrabili nel caso cadessero in mano a malintenzionati.

Le prime tecniche crittografiche, ormai elementari, venivano già utilizzate dagli antichi romani per nascondere i messaggi di guerra. In questo articolo illustrerò dei semplici codici, scritti nei linguaggi che più utilizzo ogni giorno, per applicare alcune rudimentali tecniche di criptazione.

I sistemi di criptazione più semplici, e quindi totalmente inaffidabili (perchè facilissimi da decifrare), prevedono la semplice rotazione delle lettere dell’alfabeto.

Esempi:

Cifrario di Cesare
Questa tecnica, utilizzata da Giulio Cesare, prevede che ogni lettera del messaggio in chiaro sia convertita nella lettera che si trova 3 posizioni dopo, ovvero la lettera A diventerà D, la lettera B diventerà E e così via, arrivati alla Z si ricomincia daccapo, per cui la Z diventerà C ecc. Si dice quindi che il cifrario di Cesare è a chiave 3. Per criptare il messaggio ogni lettera sarà spostata in avanti di 3 posizioni, per decriptare il messaggio e quindi leggere il messaggio in chiaro, le lettere dovranno quindi essere spostate indietro di 3 posizioni.

ROT13
Il sistema è lo stesso del precedente, ovvero si prevede la rotazione in avanti ma questa volta di 13 posizioni. Questo sistema è ancora più semplice del precedente perchè basta utilizzare la stessa tecnica sia per criptare che per decriptare, essendo il nostro alfabeto composto da 26 lettere, ogni spostamento (ROTazione) in avanti o indietro di 13 posizioni restituirà sempre la stessa lettera.
Il ROT13 viene comunemente utilizzato nei newsgroup o in altri ambiti in cui un testo lo si vuole mostrare ma in modo che non sia leggibile all’istante (ad esempio: rivelare la soluzione di un gioco o la trama di un film)

Passiamo quindi a vedere via software come effettuare queste semplici operazioni di rotazione dell’alfabeto, ovviamente i sistemi sono tanti (la bravura di un programmatore sta anche nel dover risolvere un problema utilizzando il minor numero di istruzioni possibili e la minore quantità di memoria possibile). Ho pensato quindi, anzichè di costruirmi due stringhe, una con l’alfabeto in chiaro e un’altra con l’alfabeto rotato, come fanno in molti, di utilizzare invece i codici ascii e operare su questi.

Illustro quindi come ho strutturato la mia funzione. Abbiamo la stringa di partenza, che contiene il testo criptato o da criptare ed un’ unica funzione che effettua le operazioni. La funzione accetta due parametri: “stringa” e “spostamento”. Il parametro stringa è obbligatorio e contiente la stringa da criptare o decriptare, il parametro spostamento può essere omesso, se viene omesso assume di default il valore 13, e indica di quante posizioni devono essere spostate le lettere, 13 per criptazione/decriptazione in ROT13, 3 per criptazione secondo Cesare. Per la decriptazione secondo Cesare bisognerebbe spostare le lettere indietro anzichè avanti, per facilitarmi le cose e ridurre la quantità di codice effettuo invece uno spostamento in avanti di 23 posizioni (26 lettere dell’alfabeto – 3), quindi passerò 23 come parametro se voglio decriptare secondo Cesare. La spiegazione del meccanismo della funzione dovrebbe chiarire questi concetti:

La funzione determina dapprima la lunghezza della stringa, effettua quindi un ciclo dall’inizio alla fine della stringa in maniera da estrarre ed analizzare un carattere alla volta. Di ogni carattere estratto viene trovato il corrispondente codice ascii, si controlla quindi che il codice ascii del carattere estratto rientri tra 65 e 90 (per le lettere maiuscole) o tra 97 e 122 (per le lettere minuscole), se il codice ascii non rientra in uno di questi due intervalli allora il carattere viene lasciato tal quale. Se il carattere estratto è invece una lettera la funzione somma il valore del parametro “spostamento” al codice ascii del carattere che sta analizzando. Si controlla quindi che il numero ottenuto non superi il valore ascii massimo (90 per le maiuscole o 122 per le minuscole), se ciò si verifica bisogna ricominciare dalla prima lettera e lo faccio in questo modo che illustro con un esempio:

Devo criptare la lettera v (minuscola, che ha codice ascii 118), utilizzando il ROT13, la mia funzione effettuerà quindi la somma 118+13=131, ma 131 supera il massimo consentito per le lettere minuscole (ovvero 122), effettuo quindi la sottrazione per vedere “di quanto” ho superato il massimo: 131-122=9, bene, ora sommo il 9 al codice ascii della prima lettera dell’alfabeto corrispondente (a, minuscola, che ha codice ascii 97) e tolgo ancora 1 per cominciare la rotazione dall’inizio: 97+9-1=105, che è il codice ascii della lettera i (minuscola).

Ottenuto quindi il codice ascii del risultato, lo converto nel carattere corrispondente e lo aggiungo quindi alla stringa del risultato, costruisco quindi la stringa di uscita della funzione un carattere alla volta. La funzione così scritta è quindi facilmente utilizzabile anche per effettuare rotazioni di un qualsivoglia numero di caratteri (massimo 25, da 26 in poi non avrebbe senso), basta ricordare che il procedimento per decriptare deve avere come parametro “rotazione” 26 – il numero di posizioni usate per criptare. Nulla vieta che per criptare vogliamo andare indietro anzichè in avanti come si fa di solito, tutto sta ad utilizzare la fantasia.

Passiamo quindi ad analizzare come questo può essere ottenuto mediante vari linguaggi di programmazione.

Visual Basic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
' Rotazione alfabeto
' By Bernardo Giovanni
' www.settorezero.com
Private Function Rotazione(ByVal stringa As String, Optional ByVal spostamento As Integer = 13) As String
	Dim A, ascii, asciiout As Integer
	For A = 1 To Len(stringa) 'ciclo per tutta la lunghezza della stringa passata alla funzione
		ascii = Asc(Mid(stringa, A, 1)) 'recupero il codice ascii del carattere corrente
		' controllo se il carattere corrente è maiuscolo
		If ascii >= 65 And ascii <= 90 Then
			'si, è un carattere maiuscolo, sposto il codice ascii in avanti della quantità passata alla funzione
			asciiout = ascii + spostamento
			'se ho superato il valore di 90 (Z maiuscola), allora ricomincio dal primo carattere maiuscolo
			If asciiout > 90 Then
                asciiout = (asciiout - 90) + 64
	        End If
		' controllo se il carattere corrente è minuscolo
		ElseIf ascii >= 97 And ascii <= 122 Then
			'si, è un carattere minuscolo, sposto il codice ascii in avanti della quantità passata alla funzione
			asciiout = ascii + spostamento
			'se ho superato il valore di 122 (z minuscola), allora ricomincio dal primo carattere minuscolo
			If asciiout > 122 Then
            	asciiout = (asciiout - 122) + 96
			End If
   		Else
			' se mi trovo qui vuol dire che il carattere analizzato al momento non è ne maiuscolo ne minuscolo per cui lo riporto tal quale
			asciiout = ascii
		End If
	' mi costruisco il valore di uscita della funzione, aggiungendo uno alla volta i codici ascii ottenuti
	Rotazione = Rotazione & Chr(asciiout)
	Next A
End Function

Puoi scaricare l’esempio già scritto e testato:
[download#5#size]

Tale funzione è utilizzata anche nel programma Rotopad

In breve, per i non addetti ai lavori:

Chr è la funzione per ricavare il carattere dal codice ascii numerico
Asc è la funzione complementare di Chr, ovvero restituisce il codice ascii numerico del carattere
Len restituisce la lunghezza della stringa e i commenti sono preceduti da un singolo apice.
Mid serve ad estrarre uno o più caratteri da una stringa (il primo carattere ha posizione 1)

In Visualbasic volendo quindi ottenere la codifica in ROT13 di una stringa, basterà richiamare la funzione in questo modo:

stringa = "Ciao a tutti!"
stringaout = Rotazione(stringa)

come si vede non ho specificato il parametro “spostamento” dato che di default viene assunto 13 dalla funzione, se invece volevo criptare secondo l’algoritmo di Cesare (che prevede una rotazione in avanti di 3 posizioni) avrei fatto:

stringa = "Ciao a tutti!"
stringaout = Rotazione(Stringa,3)

per decriptare invece, devo ricordarmi di dare un valore a spostamento pari a 26 – il numero delle posizioni usate per la criptazione

PHP

In PHP il carattere dal codice ascii viene ottenuto tramite una funzione che pure si chiama Chr, la funzione complementare di CHR in PHP invece si chiama Ord. La funzione per estrarre un carattere alla volta è Substr e la funzione per determinare la lunghezza di una stringa è StrLen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
= 65 && $ascii <= 90)
			{
			// si, è un carattere maiuscolo, sposto il codice ascii in avanti della quantità passata alla  funzione
			$asciiout = $ascii + $spostamento;
			// se ho superato il valore di 90 (Z maiuscola), allora ricomincio dal primo carattere maiuscolo
			if ($asciiout > 90)
				{
                $asciiout = ($asciiout - 90) + 64;
				}
			}
		// controllo se il carattere corrente è minuscolo
		else if ($ascii >= 97 && $ascii <= 122)
			{
   			// si, è un carattere minuscolo, sposto il codice ascii in avanti della quantità passata alla funzione
			$asciiout = $ascii + $spostamento;
			// se ho superato il valore di 122 (z minuscola), allora ricomincio dal primo carattere minuscolo
			if ($asciiout > 122)
				{
       			$asciiout = ($asciiout - 122) + 96;
				}
			}
		// il carattere corrente non è ne maiuscolo ne minuscolo, lo riporto tal quale
		else
			{
  			$asciiout = $ascii;
			}
		// mi costruisco il valore di uscita della funzione, aggiungendo uno alla volta  i codici ascii ottenuti
		$StringaOut = $StringaOut.chr($asciiout);
		} // Fine ciclo For
	return $StringaOut; // valore di ritorno della funzione
	} // Fine funzione
?>

Puoi scaricare l’esempio già scritto e testato:
[download#4#size]

JAVASCRIPT

In Javascript non esistono funzioni uguali a CHR, ASC o ORD, e per ricavare il codice ascii di un carattere si usa la seguente sintassi:

codice = 'a'.charCodeAt(0); // questo per ricavare il codice ascii del carattere a
// 0 indica alla funzione di ricavare il codice ascii del carattere
// che si trova alla posizione 0 (ovvero in prima posizione)

la funzione complementare invece si ottiene con:

carattere = String.fromCharCode(97);
// sostituire al posto di 97 il codice ascii che si vuole

la lunghezza di una stringa la si ottiene invece con:

stringa.length // 'stringa ' è il nome della stringa

La funzione per estrarre un carattere alla volta in questo caso non è necessaria, dal momento che possiamo sfruttare charCodeAt(x), dove sfruttando x incrementiamo man mano la posizione nella stringa. La stessa funzione scritta in Javascript quindi diventa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Rotazione alfabeto
// By Bernardo Giovanni
// www.settorezero.com
function rotazione(stringa, spostamento)
	{
	var a=0; // contatore per ciclo FOR
	var StringaOut=""; // Stringa di uscita
	var ascii=0; // variabile che contiene il codice ascii del carattere corrente
	var asciiout=0; // variabile che contiene il codice ascii del carattere di uscita
 
	if (spostamento==null)
		{
		// se l'argomento spostamento viene omesso, gli assegno il valore 13
		spostamento=13;
		}
 
	for (a=0; a= 65 && ascii <= 90)
			{
			// si, è un carattere maiuscolo, sposto il codice ascii in avanti della quantità indicata dalla funzione
			asciiout = ascii + spostamento;
			// se ho superato il valore di 90 (Z maiuscola), allora ricomincio dal primo carattere maiuscolo
			if (asciiout > 90)
				{
				asciiout = (asciiout - 90) + 64;
				}
			}
    	// controllo se il carattere corrente è minuscolo
		else if (ascii >= 97 && ascii <= 122)
			{
       		// si, è un carattere minuscolo, sposto il codice ascii in avanti della quantità indicata dalla funzione
			asciiout = ascii + spostamento;
			// se ho superato il valore di 122 (z minuscola), allora ricomincio dal primo carattere minuscolo
			if (asciiout > 122)
				{
               	asciiout = (asciiout - 122) + 96;
				}
	   		}
		// il carattere corrente non è ne maiuscolo ne minuscolo, lo riporto tal quale
		else
			{
    		asciiout = ascii;
    		}
		// mi costruisco il valore di uscita della funzione, aggiungendo uno alla volta i codici ascii ottenuti
		StringaOut = StringaOut + String.fromCharCode(asciiout);
		} // Fine ciclo For
	return (StringaOut); // valore di ritorno della funzione
	} // Fine funzione

Puoi scaricare l’esempio già scritto e testato:
[download#3#size]

Per giocare con le parole e testare il funzionamento, puoi scaricare Rotopad



Questo articolo ti è stato utile? Ti ha permesso di risolvere un problema o di migliorare le tue applicazioni? Ci lavori? Ti ha permesso di scrivere la tua tesina? Ti ha semplicemente fatto spendere un po' del tuo tempo in maniera costruttiva? Allora clicca il banner qui sotto:


Settorezero.com è un blog personale di Giovanni Bernardo aperto dal 25 Ottobre 2007. Non è una testata giornalistica né un sito a carattere commerciale.
Settorezero.com, il logo Zroid™ e la tagline "Play embedded electronics™" sono copyright ©2007÷2019 Giovanni Bernardo.
La navigazione su settorezero.com e la fruizione dei contenuti ivi presenti sono soggette ai seguenti Termini di utilizzo - Informativa sulla privacy - Utilizzo dei Cookie.
Il tema di questo sito è basato sul tema Fusion per wordpress, realizzato originariamente da digitalnature e fa uso del plugin Wassup per il computo delle statistiche.
Per poter contattare il gestore del sito potete utilizzare la sezione contatti o inviare una email a gianni[at]settorezero[dot]com.
Per seguire gli aggiornamenti del blog Settorezero, oltre al feed RSS, puoi anche seguire la pagina Facebook o iscriverti al canale Telegram.
Su Twitter, invece, pubblico un po' di tutto e, quando mi va, uso anche Tumblr - Google+ - Blogspot - Youtube.