PRATIQUE PHP 
Générer une image "captcha" avec PHP
 
Choix de la police, fond aléatoire, angle de lecture : les fonctionnalités de la bibliothèque GD autorisent la création à la volée d'images de test sécurisées pour formulaires Web. (22/09/2006)
  Forum

Réagissez dans les forums de JDN Développeurs

Bien que fortement critiqués pour leur manque d'accessibilité, les captchas restent une solution très prisée pour la protection des formulaires Web de connexion ou d'envoi de données, afin d'éviter de les voir exploités répétitivement par des scripts aux mauvaises intentions...

Le terme captcha est en fait un acronyme pour Completely Automated Public Turing test to tell Computers and Humans Apart, c'est-à-dire "test Turing public et complètement automatisé pour faire la différence entre les ordinateurs des humains". Le principe est simple : pour prouver qu'il est humain, le visiteur doit répondre positivement à un test spécialement créé pour lui, ce que ne peut accomplir un script lambda.

Dans la plupart des cas, un captcha affiche une image contenant une chaîne de lettres plus ou moins brouillées et lisibles, afin de contourner les algorithmes de lecture d'image des scripts sophistiqués. Les systèmes de captcha les mieux conçus proposent des images le plus possible différentes à chaque session (police, positionnement, fond, perturbation), voire une alternative sonore, elle-même générée par le serveur, pour les captchas trop illisibles ou, simplement, les utilisateurs mal-voyants.

Nous vous présentons ici un système probablement pas assez élaboré pour rester invaincu face aux scripts les plus sophistiqués, mais permettant de voir les différentes fonctions en action pour un tel traitement. Bien entendu, nous faisons ici massivement appel à la bibliothèque interne GD.

L'idée est donc de générer de manière aléatoire l'ensemble du contenu de l'image, afin de s'assurer d'une certaine sécurité : texte (qui devra d'ailleurs être conservé dans les variables de session pour vérifier que le visiteur à bien rempli le champ du formulaire testeur), image de fond, caractéristique de la police (taille, graisse, positionnement, angle, fonte utilisée, couleur), peut-être la taille de l'image elle-même, ou des traits aléatoires qui viennent troubler encore le visiteur non humain.

Nous présentons simplement les fonctions impliquées. Ainsi, l'image de fond sera importée grâce à une première image, qui charge un fichier déterminé (choisi parmi une série d'image nommée "picX.jpg", par exemple.
  1. $rnd = rand(1, 26);
  2. $fond = imagecreatefromjpeg("img/pic".$rnd.".jpg");
Ce fond est ensuite collé sur l'image définitive, dont la taille peut également être aléatoire :
  1. $largeur = 120;
  2. $hauteur = 120;
  3. $image = ImageCreate($largeur, $hauteur);
  4. ImageCopy($image, $fond, 0, 0, 0, 0, $largeur, $hauteur);
  5. ImageDestroy($fond);
Nous n'utilisons ici que la fonte comme élément aléatoire du texte :
  1. $fontes = array("tahoma.ttf", "BSSYM7.TTF", "GARAIT.TTF", "georgia.ttf");
  2. $rnd = rand(0, count($fontes)-1);
  3. $police = $fontes[$rnd];
  4. $couleurTexte = imagecolorallocate($image, 255,255,255); // blanc
  5. ImageTTFText($image, 12, 12, 40, $hauteur/2, $couleurTexte, $police, $texte);
ImageTTFText() présente également l'intérêt, avec son 3e argument, de pouvoir donner un angle à la police, possiblement aléatoire. On pourrait même réaliser une boucle au travers de la chaîne, qui afficherait chaque caractère avec une police, une couleur, un angle différents... dans les limites de la lisibilité, bien sûr.

Tout ceci fait, il ne reste plus qu'à l'envoyer au navigateur :
  1. header("Content-type: image/jpg");
  2. imagejpeg($image);
  3. imagedestroy($image);
 
Xavier Borderie, JDN Développeurs
 
 
Accueil | Haut de page