Formation référencement

Captcha : Conversion d’image en PHP

Ecrit par lemoussel le Lundi 2 novembre 2009 à 15:00 - Catégorie Captchas

Une des solutions connues pour outrepasser / bypasser les codes captchas antispam est l’utilisation d’un traitement OCR (Optical Character Recognition = Reconnaissance optique de caractères).

Pour effectuer ce type de traitement, l’image sur laquelle sera effectuée le traitement doit être soit en niveaux de gris ou en monochrome. Cette étape de transformation de l’image est une étape essentielle de tous traitements OCR car la complexité du programme et le temps de calcul s’en trouvent largement réduits.

Pour des raisons de portabilité la plupart des outils d’OCR utilise le format PNM (portable anymap) comme format d’image. L’avantage de ce type de format est de coder l’image dans sa plus simple expression. Le terme « PNM » étant une généralisation regroupant les formats réels PBM (portable bitmap file format – image binaire), PGM (portable graymap file format – image en niveaux de gris) et PPM (portable pixmap file format – image en couleur).

Les fichiers au format PNM se structurent de la même manière et n’introduisent aucune méthode de compression d’image. Les données dans ces fichiers expriment soit la valeur RVB pour le PPM, soit le niveau de gris dans le cas du PGM ou simplement avec des 1 ou 0 pour le PBM.

Par exemple pour le format PBM, qui nous intéresse, la structure est la suivante :

  • Un nombre magique (indicateur commençant par P)
  • Un caractère d’espacement
  • Largeur de l’image (codée en caractères ASCII)
  • Un caractère d’espacement
  • Hauteur de l’image (codée en caractères ASCII)
  • Un caractère d’espacement
  • Données ASCII ou binaire de l’image :
    • L’image est codée ligne par ligne en partant du haut
    • Chaque ligne est codée de gauche à droite
    • Un pixel noir est codé par un caractère 1, un pixel blanc est codé par un caractère 0
    • Les caractères d’espacement à l’intérieur de cette section sont ignorés
    • Aucune ligne ne doit dépasser 70 caractères.

Toutes les lignes commençants par # sont ignorées (ligne de commentaire).
Le caractère d’espacement peut être soit un espace, une tabulation ou une nouvelle ligne.
Le nombre magique détermine le type de format de l’image.

Le tableau ci-dessous résume les formats en fonction du nombre magique :

Format Indicateurs (ASCII, binaire) Description
PBM P4,P1 Monochrome
PGM P2,P5 Niveaux de gris
PPM P3,P6 Couleur

Il est important de noter que pour un même format d’image, on peut obtenir des tailles du fichier image différentes. Cette différence est du fait de l’application de la méthode d’écriture soit en mode binaire ou ASCII qui est beaucoup plus lourde en volumétrie.

Une image PBM binaire pourrait alors avoir cette forme :

P1
# Image PBM SEOBlackOut
320 220
11100101100101100...

Remarque : L’article de Wikipédia Portable pixmap décrit toutes les descriptions des formats PNM.

Je terminerais cette théorie, par la formule de conversion des valeurs RGB (Red, Green, Blue, pour Rouge Vert et Bleu, en français RVB) en niveaux de gris. Pour ce faire il suffit d’appliquer la formule suivante :

NG = R * 0,299 + G * 0,587 + B * 0,114

où pour un pixel donné : R exprime la composante Rouge, G la composante Verte, B la composante Bleu et NG exprimant le niveau de gris.

La binarisation de l’image (séquences successives de pixels noirs (bits 0) et blancs (bits 1)) est basée sur un seuillage brut. Cela signifie que si un pixel de l’image a un niveau de gris supérieur à une certaine valeur de seuil, il lui sera attribué la couleur blanche sinon il sera noir. Ce procédé est réalisé sur chaque pixel de l’image. Nous obtenons donc une image comportant seulement deux niveaux (valeur 0 ou 1).

La détermination du seuil de binarisation peut s’effectuer à partir de l’histogramme des niveaux de gris afin de déterminer les deux pics de population de pixels. On pourra ainsi, par exemple, choisir la valeur de niveau de gris médiane entre ces deux pics. Néanmoins, il existe de nombreuses autres manières d’effectuer le seuillage : valeur moyenne de l’intensité sur l’ensemble de l’histogramme, valeur médiane de l’intervalle des niveau de gris ([0, 255]), …

Dans l’exemple de code en PHP ci-dessous, ce seuil de binarisation a été fixée arbitrairement à la valeur 170.

Vous avez tout suivi ? alors passons à la pratique.

Voici le code PHP de codage d’une image au format PBM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function convertToPBM( $originalFile, $outputFile ) 
{
    if(($handlePBM = fopen($outputFile . '.bpm', 'w')) === FALSE)
        die("Impossible de creer le fichier BPM : $outputFile");
	$ImgWidth = imagesx ($originalFile);
	$ImgHeight = imagesy ($originalFile);	
 
	fprintf ($handlePBM, "P1\n%d %d\n255\n", $ImgWidth, $ImgHeight);
    for ($y=0; $y<$ImgHeight; $y++)
        for ($x=0; $x<$ImgWidth; $x++)
        {
            $rgb = imagecolorat($originalFile, $x, $y);
            $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;
 
            $gs = (($r*0.299)+($g*0.587)+($b*0.114));
			if ( $gs > 170 ) // seuil de binarisation 
				fwrite($handlePBM, '1'); 
            else
				fwrite($handlePBM, '0'); 
		}
	fclose($handlePBM);
}

Par exemple pour le traitement d’une image au format PNG, le fonction convertToPBM() sera exécutée de la manière suivante :

1
2
3
4
....
   $ImgSrcCaptcha = imagecreatefrompng('captcha-source.png');
   convertToPBM($ImgSrcCaptcha, 'captcha');
.....

Et voilà le résultat obtenu sur un captcha bien connu :

Image PNG Source : captcha source

Image PBM : captcha-pbm

Commentaires (18)

Catégorie: Captchas


18 Commentaires

Commentaire par ytsaeb

Lundi, 2 novembre , 2009 à 21:41

images invisibles… ……………… …………………

Commentaire par admin

Lundi, 2 novembre , 2009 à 21:58

Oubli de ma part, c’est corrigé, merci :)

Commentaire par Canyon

Lundi, 2 novembre , 2009 à 22:49

Petit cachotier! :-]

T’as un taux de réussite de combien avec ça?

Commentaire par ytsaeb

Lundi, 2 novembre , 2009 à 22:53

J’applaudis la prose qui est ici tenue.

Commentaire par 512banque

Mardi, 3 novembre , 2009 à 13:06

Bravo lemoussel, c’est de la haute voltige :)

Commentaire par admin

Mercredi, 4 novembre , 2009 à 12:32

Bon Lemoussel , faut s’attaquer à recaptcha maintenant, 2 réussites sur 50 essais chez moi, je suis sûr qu’on peut faire bien mieux ;)

Commentaire par lemoussel

Mercredi, 4 novembre , 2009 à 13:21

Avec plaisir …. :)

mais avant je vais m’entrainer avec le captcha de Pligg ;) (mise au point des interfaces PHP avec certains outils ;) )
Il est plus simple ! et j’ai remarqué sur certain site une évolution du captcha Pligg vers recaptcha

Commentaire par admin

Mercredi, 4 novembre , 2009 à 13:25

J’ai ce qu’il faut pour pligg, y a une façon de le bypass sans avoir besoin de le traiter par OCR (dépend de la version de pligg) et j’ai aussi la méthode OCR avec nettoyage préalable à l’aide de la fameuse lib, mais pas en php, faut que je t’envoie le tout… et d’autres choses d’ailleurs ;)

Commentaire par admin

Mercredi, 4 novembre , 2009 à 13:27

De toute façon à force d’être spammé, la plupart de ces scripts commencent à proposer recaptcha, de plus Google ayant acheté recaptcha…

Commentaire par Ben

Vendredi, 6 novembre , 2009 à 6:36

Interressant !

quel OCR utilisez-vous ?

Commentaire par nierdz

Vendredi, 6 novembre , 2009 à 17:55

Perso, en bash, avec un dédié, j’utilise imagemagick pour la conversion en monochrome et tesseract ( by google :) ) pour la partie OCR et sur les captcha de freeglobes (comme dans ton exemple) le taux de réussite est très bon.

Commentaire par admin

Vendredi, 6 novembre , 2009 à 18:03

+1 nierdz ;) sauf que je fais en php au lieu de bash.

Commentaire par 512banque

Vendredi, 6 novembre , 2009 à 18:03

ça, ça fait bien l’affaire, même si l’apprentissage est un peu long :
http://www.phpclasses.org/browse/package/2874.html

en tout cas ça doit passer nickel pour du freeglobes :p

Commentaire par lemoussel

Vendredi, 6 novembre , 2009 à 18:48

Je teste avec Gocr et PHP. Ça passe aussi
Bon entre nous, ce captcha n’est pas très compliqué a décoder.
Pour ReCaptcha c’est une autre affaire ;)

Commentaire par admin

Vendredi, 6 novembre , 2009 à 19:02

Clair qu’il est easy celui-là traitable uniquement en php sans ocr…

ReCaptcha c’est ZE challenge !

Commentaire par nierdz

Vendredi, 6 novembre , 2009 à 19:12

recaptcha c’est même un challenge pour l’oeil humain!
Une fois sur deux j’arrive à me gourer. :)
Et si quelqu’un a un début de piste pour s’y attaquer je pense que je ne serai pas le seul à trouver ça intéressant…

Par contre des captcha comme arfoo ou phpbb sont déjà plus accessibles même si ils sont plus compliqués que celui de freeglobes. En passant quelques paramètres qui vont bien à imagemagick au moment de la conversion en monochrome on arrive à avoir des taux de 50% de réussite environ.

Commentaire par SEO China

Jeudi, 12 novembre , 2009 à 3:48

Oooo sympa, je vais mettre en pratique pour les annuaires categorizator et dérivés…

Reste plus qu’à combiner ca avec l’autofil du post d’au dessus et ce sera parfait hahaha ^^

merci !

Commentaire par Xiu

Mercredi, 17 février , 2010 à 15:59

Et après tu fais comment pour afficher le BPM ?

Les commentaires sont fermés pour cet article.



SEO BLACKOUT

Site web dédié aux techniques de référencement et de positionnement de sites web sur Google.

Certaines parties du site sont en accès restreint, ces espaces sont réservés à la SEO Black Hat Team.


Don't Be Evil !