Vediamo e commentiamo innanzitutto, il sorgente di verimage.php:
<?php
/* Alcuni parametri configurabili */
$boxW=128; // Larghezza immagine
$boxH=32; // Altezza immagine
$codelen=6; // Lunghezza del codice
$snow=4; // effetto neve 0=no, o intero % copertura
/* Dichiara che lo stream trasmesso è un file immagine PNG */
header("Content-Type: image/png");
/* Inizializza la sessione */
session_start();
/* inizializza il generatore di numeri casuali */
srand((double)microtime()*1000000);
/* Crea un codice di verifica casuale
e lo immagazzina nella sessione in
modo che processform.php possa recuperarlo
*/
$string=strtolower(substr(md5(rand()),7,$codelen));
$_SESSION['verification_string']=$string;
/* Creazione immagine di dimesioni $boxW x $boxH */
$im = ImageCreate($boxW, $boxH);
/* Colori */
$white = ImageColorAllocate($im, 255, 255, 255);
$black = ImageColorAllocate($im, 0, 0, 0);
/* Riempie lo sfondo di nero */
ImageFill($im, 0, 0, $black);
/* creo la neve */
if($snow>0) {
$n=($boxW*$boxH)*($snow/100);
for($i=0;$i< $n;$i++) {
$x=rand(1,$boxW-1);
$y=rand(1,$boxH-1);
imagesetpixel($im, $x,$y, $white);
}
}
/* seleziona un font a caso tra quelli di sistema */
$font=rand(3,5);
/* Calcola ampiezza scritta */
$w=strlen($string)*ImageFontWidth($font);
$h=ImageFontHeight($font);
/* Posizione casuale */
$x=rand(1,($boxW-$w-1));
$y=rand(1,($boxH-$h-1));
/* scrive nell'immagine la stringa di controllo */
ImageString($im, $font, $x, $y, $string, $white);
/* output al browser*/
ImagePNG($im);
/* Distruggo l'immagine in memoria */
ImageDestroy($im);
?>
Notiamo che all’inizio del file ci sono alcune variabili di configurazione, modificando le quali è possibile cambiare l’aspetto dell’immagine che rappresenta il codice di controllo.
In particolare è possibile regolare l’altezza e la larghezza in pixel dell’immagine, il numero di caratteri che comporranno il codice di controllo e l’effetto neve di cui parleremo tra un po’.
Successivamente troviamo la chiamata alla funzione header() che modifica il tipo mime nell’header HTTP. In pratica nel nostro script comunichiamo al browser, che sta ricevendo la pagina, che il flusso dei dati in arrivo non è una pagina html, bensì un file di immagine di tipo PNG. Se preferite utilizzare come tipo di immagine il formato Jpeg, potete modificare il content type in “image/jpg”.
Di seguito viene inizializzata la sessione, viene creato un codice alfanumerico casuale del numero di caratteri richiesti e viene memorizzato nella sessione, in modo da poterlo recuperare in un secondo momento, per effettuare il controllo.
Viene quindi creato in memoria un oggetto di tipo immagine delle dimensioni stabilite, viene riempito con il colore nero e poi viene creato un “effetto neve” casuale.
Tale effetto neve è solo un esempio di come è possibile, peggiorando la qualità dell’immagine, ostacolare il lavoro dei software di OCR. Il cervello umano, invece, essendo il più perfezionato degli OCR, ha una maggiore probabilità di interpretare correttamente i caratteri del codice di controllo che vengono impressi sull’immagine con la funzione ImageString().
Agendo sul parametro $snow è possibile aumentare o diminuire il disturbo. Occorre trovare un punto di equilibrio in modo che il codice rimanga leggibile da un umano ma sia difficilmente interpretabile da un OCR.
Ciao,
ho apprezzato molto il tuo tutorial, e vorrei inserirlo all’interno di un GuestBook, per evitare di scrivere messaggi di spam…
Ho studiato molto bene le tue pagine, e credo anche di aver capito come funziona il sistema, tranne un po’ per la pagina verimage.php, che mi prometto di apprendere col tempo…
Ma veniamo al problema….
Tu effettui il controllo della validità del codice, nella pagina processform.php; io avrei bisogno di effettuare questo controllo in javascript, e senza richiamare un’altra pagina, ma svolgendo tutto nella pagina di scrittura dei messaggi (si tratta di un guestbook….)
E’ possibile controllare l’effettiva corrispondenza tramite javascript?
Grazie…
ti lascio la mia mail: eliomarotta@alice.it
Elio,
Non credo sia possibile farlo in maniera diretta perché dovresti mettere il codice di sicurezza nel sorgente Javascript che quindi diventerebbe “visibile”.
Semmai potresti utilizzare qualcosa tipo Ajax per controllare dinamicamente il codice senza però esporlo. Non è una cosa semplicissima da fare, ma si può fare.
Ciao. Veramente un tutorial utile, e funziona bene per le mie necessità. Appena ho finito di implementarlo sul sito che gestisco, ti posto il link così puoi guardarci. Grande!
Ciao devo ammettere che lo script è eccezionale… e spero di utilizzarlo all’interno del mio libro degli ospiti che ogni giorno mi tocca cancellare i messaggi spam… purtroppo ho riscontrato un piccolo problema, praticamente non si carica l’immagine col codice OCR… mi aiuti? Grazie ;o)
Ciao,
lo script è proprio quello che stavo cercando!
Purtroppo anch’io come etikettaindipendente non riesco a caricare l’immagine col codice OCR.
Potresti dare delucidazioni in merito.
Grazie
abbiamo fatto qualche indagine ed è venuto fuori che, almeno nel caso di etikettaindipendente, il problema sembra essere la mancanza delle librerie grafiche GD nell’installazione del php.
Quindi provate a usare phpinfo() per verificare che il supporto alle librerie grafiche GD sia abilitato e funzionante!
Si si Meg, hai proprio ragione, è proprio la mancanza delle librerie grafiche GD nell’installazione del php… ma ti comunico che presto risolverò il problema perché ho cambiato azienda e qui ci sono 2 programmatori…. presto vi farò sapere, buon lavoro a tutti