Fabio Donatantonio

Resta connesso

Software Developer / Adjunct Professor

Il cifrario di Vigenère in PHP

In due articoli precedenti abbiamo analizzato, grazie a PHP, due algoritmi di cifratura: Cesare e Blowfish.
Il primo al solo scopo didattico-storico, mentre il secondo pienamente utilizzabile all’interno delle nostre applicazioni, viste le sue potenzialità e il grado di sicurezza che fornisce.

Il cifrario di Vigenère è il più semplice dei cifrari polialfabetici. Si basa sull’uso di un versetto (chiave) per controllare l’alternanza degli alfabeti di sostituzione.
Il metodo si può considerare una generalizzazione del cifrario di Cesare; invece di spostare sempre dello stesso numero di posti la lettera da cifrare, questa viene spostata di un numero di posti variabile ma ripetuto, determinato in base ad una parola chiave e da scrivere ripetutamente sotto il messaggio, carattere per carattere:

testo in chiaro: CIAO MAMMA CIAO
chiave: CHIA VECHI AVEC
testo cifrato: EPIO HEOTI CDEQ

Il testo cifrato si ottiene spostando la lettera chiara di un numero fisso di caratteri, pari al numero ordinale della lettera corrispondente della chiave.
Per semplificare la cifratura/decifratura Vigenère propose una matrice quadrata (26 X 26) composta da alfabeti ordinati e spostati.
Nel codice che andremo a sviluppare utilizzeremo questa versione “classica” dell’algoritmo, difatti realizzeremo la matrice e la cifratura/decifratura verrà eseguita su di essa.
In fondo all’articolo è possibile provare e scaricare il codice completo.

Passiamo quindi al codice della classe che chiameremo vigenere.php.
La classe si comporrà dei seguenti metodi:

  • Costruttore per la realizzazione della matrice (tavola di Vigenère)
  • Metodo di cifratura
  • Metodo di decifratura
  • Metodo che stampa a video la tavola di Vigenère

Ecco il codice PHP:

<?php
class Vigenere{
	var $alfabeto = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N', 'O','P','Q','R','S','T','U','V','W','X','Y','Z');
	var $matrice;
	var $chiave;
	
	// Il costruttore imposta la chiave e realizza la matrice
	function Vigenere($chiave){
		$this->chiave = str_replace(array(" ",".",",",";"),"", $chiave);
		$app1 = array();
		$app2 = array();
		$alfabeto_app = array();
		for($i=0; $i<26; $i++){
			$k=0;
			$app1 = array_slice($this->alfabeto,0,$i);
			$app2 = array_slice($this->alfabeto,$i);
			$this->matrice[$i] = array_merge($app2,$app1);
		}
	}
	
	// Metodo che stampa la matrice
	function stampaTavola(){
		echo "<table border='1' cellpadding='1' cellspacing='0'>
		<tr><td rowspan='27' width='50px' align='center'>T<br>E<br>S<br>T<br>O<br> <br>I<br>N<br> <br>C<br>H<br>I<br>A<br>R<br>O<br></td><td colspan='26' align='center' height='50px'>CHIAVE</td></tr>";
		for($i=0; $i<26; $i++){
			echo "<tr>";
			for($j=0; $j<26; $j++){
				echo "<td align='center'>".$this->matrice[$i][$j]."</td>";
			}
			echo "</tr>";
		}
		echo "</table>";
	}
	
	// Metodo per la cifratura
	function cifratura($testo){
		$txt_cifrato = "";
		$l_chiave = strlen($this->chiave);
		$k = 0;
		for($i=0; $i<strlen($testo); $i++){
			$chr_t = substr($testo,$i,1);
			$chr_c = substr($this->chiave,$k,1);
			
			if(in_array(strtoupper($chr_t),$this->alfabeto) && in_array(strtoupper($chr_c),$this->alfabeto)){
				$x = array_search(strtoupper($chr_t),$this->alfabeto);
				$y = array_search(strtoupper($chr_c),$this->alfabeto);
				$txt_cifrato = $txt_cifrato.$this->matrice[$x][$y];
				$k++;
			}else{
				$txt_cifrato = $txt_cifrato.strtoupper($chr_t);
			}
			if($k==$l_chiave) $k = 0;
		}
		return $txt_cifrato;
	}
	
	// Metodo per la decifratura
	function decifratura($testo){
		$txt_decifrato = "";
		$l_chiave = strlen($this->chiave);
		$k = 0;
		for($i=0; $i<strlen($testo); $i++){
			$chr_t = substr($testo,$i,1);
			$chr_c = substr($this->chiave,$k,1);
			if(in_array(strtoupper($chr_t),$this->alfabeto) && in_array(strtoupper($chr_c),$this->alfabeto)){
				$colonna = array_search(strtoupper($chr_c),$this->alfabeto);
				$riga = 0;
				for($c=0; $c<26; $c++){
					if($this->matrice[$c][$colonna]==$chr_t){
						$riga = $c;
						break;
					}
				}
				$txt_decifrato = $txt_decifrato.$this->matrice[$riga][0];
				$k++;
			}else{
				$txt_decifrato = $txt_decifrato.$chr_t;
			}
			if($k==$l_chiave) $k = 0;
		}
		return $txt_decifrato;
	}
}
?>

Utilizzando un array contenete l’alfabeto, realizzeremo la matrice semplicemente tagliando ad ogni riga l’alfabeto in due parti, grazie alla funzione array_slice, per poi ricomporlo in maniera inversa.
Grazie a questa matrice i metodi cifratura e decifratura risultano abbastanza semplici:
– cicliamo lettera per lettera sul testo in chiaro e sulla chiave
– per ogni coppia di lettere (chiaro-chiave) verifichiamo le posizioni nell’alfabeto
– le coordinate x e y ottenute individueranno la lettera cifrata nella matrice
Il cuore del codice di cifratura è composto essenzialmente dalle tre righe:

$x = array_search(strtoupper($chr_t),$this->alfabeto);  
$y = array_search(strtoupper($chr_c),$this->alfabeto);  
$txt_cifrato = $txt_cifrato.$this->matrice[$x][$y];  

Per la decifratura il procedimento è lo stesso, richiede solo una ricerca differente basata sulle colonne identificate dalle lettere che compongono la chiave.
Infine è presente un metodo denominato stampaTavola che visualizza a video la matrice favorendo la verifica manuale del processo di cifratura/decifratura.

La classe va così richiamata:

<?php
require_once 'vigenere.php';

$vigenere = new Vigenere($chiave);
$vigenere->stampaTavola();
$txt_cifrato = $vigenere->cifratura($testo);
$txt_decifrato = $vigenere->decifratura($txt_cifrato);
?>

All’interno della cartella contenente il codice completo sono presenti i seguenti file:

  • vigenere.php (la classe vista sopra)
  • test.php (lo script che effettua la cifratura/decifratura)
  • index.html (un form per il test di coppie chiave-testo in chiaro)

Cliccando qui è possibile vedere in azione il codice.

Cliccando qui è possibile scaricare il codice.

Fabio Donatantonio

Fabio Donatantonio. Analista e sviluppatore full-stack di applicazioni web in linguaggio PHP. Professore a Contratto per le cattedre di Fondamenti di Informatica e Archivistica Digitale presso Università degli Studi eCampus. Dal 2008 curatore del sito www.donatantonio.net, da sempre appassionato di programmazione, mare, sigari e... musica.

Ti potrebbe piacere anche

1 Comment

  1. Il disco cifrante di Alberti in PHP | Fabio Donatantonio

    18th Lug 2011 - 23:21

    […] il cifrario di Cesare e Vigenère continuiamo l’excursus sulle tecniche di cifratura che hanno contraddistinto la storia e […]

Leave a reply

Your email address will not be published. Required fields are marked *

 

Didattica

Università degli Studi eCampus
Data Evento
09/02/2021
14:30
Esame Archivistica Digitale e Informatica per le Scienze Umane - Cds Letteratura, Lingua e Cultura Italiana - Lettere
09/02/2021
14:30
Esame Introduzione all'Archivistica Digitale e all'Informatica per le Scienze Umane - Cds Letteratura, Arte, Musica e Spettacolo - Lettere
09/02/2021
17:30
Esame Abilità Informatiche e Telematiche - Cds Design e Discipline della Moda - Lettere
09/02/2021
17:30
Esame Abilità Informatiche e Telematiche - Cds Letteratura, Arte, Musica e Spettacolo - Lettere
Risorse
Guida HTML/CSS per principianti (link)
Introduzione agli ipertesti (link)
Esercizi guidati in Java (link)
Intelligenza artificiale (link)
Libri
Fondamenti di Informatica (2011) (link)
Informatica per le Scienze Umane (2011) (link)
Fondamenti di Informatica (2014) (link)
Pagina Docente
uniecampus.it - Scheda Docente (link)
Contatti
fabio.donatantonio[at]uniecampus.it

JWhisper, sviluppato presso il Dipartimento di Informatica Applicata dell'Università degli Studi di Salerno:

Stay Connected

Twitter

Le mie foto

Foto di Fabio Donatantonio
×