CAPTCHA - un termen familiar pentru unii dintre noi, mai putin cunoscut altora, dar cu siguranta ceva cu care toti ne-am intalnit la un moment dat.
Generalizat, CAPTCHA (acronim pentru Completely Automated Public Turing test to tell Computers and Humans Apart) reprezinta o modalitate oarecare de a face distinctia intre un utilizator uman si o masina (computer), dupa cum spune si numele. Acest mecanism a aparut din nevoia de securitate, fiind pentru prima oara implementat in sistemul de inregistrare de la Yahoo, si consta in prezentarea unei imagini ce continea un cuvant distorsionat, cerandu-i-se utilizatorului sa recunoasca cuvantul din imagine, lucru foarte greu de realizat, daca nu chiar imposibil, de catre o masina. Cu timpul, conceptul s-a raspandit si s-a dezvoltat, ajungand la forme foarte diverse care impuneau utilizatorilor una din urmatoarele:
Unde devine folositor acest sistem? CAPTCHA este util intr-unul din urmatoarele cazuri, fara a se limita insa la acestea:
In clipa de fata exista pe internet o multime de astfel de solutii, gratuite sau comerciale, dar tocmai gradul lor de raspandire le face vulnerabile. Unele folosesc cuvinte din dictionar, usor de recunoscut de catre roboti, altele folosesc imagini comune, care pot fi indexate anterior, altele folosesc text nedistorsionat si lista punctelor slabe ar putea continua.
In cele ce urmeaza, vom realiza un sistem simplu, care va genera un cod aleatoriu, a carei recunoastere vom incerca s-o ingreunam cat mai mult cu putinta.
ATENTIE!
Acesta este un tutorial. Scopul sau este de a invata pe cei care-l citesc un anumit lucru. Scopul sau NU este acela de a oferi pur si simplu o solutie gratuita, de aceea va trebui sa cititi cu atentie tot ceea ce urmeaza si sa efectuati unele modificari in functie de aplicatia dumneavoastra.
In primul rand vom crea un fisier de configurari ( Ex:config.php) in care vor fi definiti parametrii dupa care va fi generat codul.
$sessionVar = 'myCaptcha';
$allowedChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
$minCodeLength = 4; $maxCodeLength = 6;
$minFontSize = 24; $maxFontSize = 32;
$minLetterSpacing = 4; $maxLetterSpacing = 10;
$maxVerticalDisplacement = 15;
$maxRotationLeft = 15; $maxRotationRight = 15;
$textPadding = 5;
$bgColor = array(255, 255, 255);
$textColor = array( '200, 0, 0', '30, 200, 0', '150, 0, 200', '150, 150, 0', '100, 100, 100', 'ff0099', '99ff00' );
$fontsFolder = 'my_fonts/'; $fontFiles = array( 'elektra.ttf', 'episode1.ttf', 'lcd2bold.ttf', 'optimusprinceps.ttf', 'sams_town.ttf', 'steinerlight.ttf', 'turn_table.ttf' );
$backgroundsFolder = 'my_backgrounds/'; $backgrounds = array( 'bg_1.png', 'bg_2.png', 'bg_3.png', 'bg_4.png' );
NU UITATI SA INLOCUITI CAILE SI NUMELE FISIERELOR DE MAI SUS CU CELE FOLOSITE DE DUMNEAVOASTRA
De-ajuns cu configurarile si sa dam drumul la actiune!
Vom avea nevoie de un fisier PHP (sa-i zicem show_code.php) pe care il vom apela asa cum apelam o imagine oarecare, si anume:
<img src="show_code.php" alt="myCaptcha" />
session_start();
include_once('config.php');
$_SESSION[$sessionVar] = '';function getCharSize($fontFile, $char, $size, $angle=0){
if( is_file($fontFile) && strlen($char) == 1 && $size > 0){
$corners = @imagettfbbox( $size, $angle, $fontFile, $char );
$left = ($corners[0]>$corners[6])?$corners[6]:$corners[0];
$right = ($corners[2]>$corners[4])?$corners[2]:$corners[4];
$top = ($corners[5]>$corners[7])?$corners[7]:$corners[5];
$bottom = ($corners[1]>$corners[3])?$corners[1]:$corners[3];
$width = $right - $left + 4;
$height = abs($top - $bottom) + 4;
$return = array(
'width' =>$width,
'height' =>$height,
'bottom' =>$bottom,
'right' =>$right,
'top' =>$top,
'left' =>$left
);
}else{
$return = false;
}
return $return;
}function hex2decColor($color){
if(substr_count($color, ',') == 2){
list($red, $green, $blue) = array_map('trim', explode(',', $color));
}else{
$red = hexdec($color[0].$color[1]);
$green = hexdec($color[2].$color[3]);
$blue = hexdec($color[4].$color[5]);
}
return array('red'=>$red, 'green'=>$green, 'blue'=>$blue);
}$imgWidth = 0; $imgHeight = 0; $codeLength = rand($minCodeLength, $maxCodeLength);
for($c = 1; $c <= $codeLength; $c++){
$char[$c]['char'] = $allowedChars[rand(0, strlen($allowedChars)-1)];
$char[$c]['color'] = hex2decColor($textColor[rand(0, count($textColor)-1 )]);
$char[$c]['displacement'] = rand(0, $maxVerticalDisplacement*2) - $maxVerticalDisplacement;
$char[$c]['font'] = $fontsFolder.$fontFiles[rand(0, count($fontFiles)-1 )];
$char[$c]['size'] = rand($minFontSize, $maxFontSize);
$char[$c]['angle'] = rand(0, $maxRotationLeft + $maxRotationRight) - $maxRotationRight;
$char[$c]['space'] = rand($minLetterSpacing, $maxLetterSpacing);$properties = getCharSize($char[$c]['font'], $char[$c]['char'], $char[$c]['size'], $char[$c]['angle']); $width = $properties['width']; $height = $properties['height'];
$imgWidth += $width; if($c != $codeLength) $imgWidth += $char[$c]['space'];
if( ($height + abs($char[$c]['displacement'])) > $imgHeight ) $imgHeight = $height + abs($char[$c]['displacement']);
$_SESSION[$sessionVar] .= $char[$c]['char']; }
$imgWidth += $textPadding * 2; $imgHeight += $textPadding * 2 + $maxVerticalDisplacement;
$img = imagecreatetruecolor($imgWidth, $imgHeight);
$bg = rand(0, count($backgrounds)-1); list($bgWidth, $bgHeight) = getimagesize($backgroundsFolder.$backgrounds[$bg]);
$bgX = rand(0, $bgWidth-$imgWidth); $bgY = rand(0, $bgHeight-$imgHeight); $bgImg = imagecreatefrompng($backgroundsFolder.$backgrounds[$bg]); imagecopy($img, $bgImg, 0, 0, $bgX, $bgY, $imgWidth, $imgHeight); imagedestroy($bgImg);
$cursor = $textPadding;
for($c = 1; $c <= $codeLength; $c++){
$color = imagecolorallocate($img, $char[$c]['color']['red'], $char[$c]['color']['green'], $char[$c]['color']['blue']);$properties = getCharSize($char[$c]['font'], $char[$c]['char'], $char[$c]['size'], $char[$c]['angle']); $width = $properties['width']; $height = $properties['height']; $bottom = $properties['bottom']; $y = $char[$c]['displacement'] + $maxVerticalDisplacement + $height - $bottom;
imagettftext($img, $char[$c]['size'], $char[$c]['angle'], $cursor, $y, $color, $char[$c]['font'], $char[$c]['char']); $cursor += $width + $char[$c]['space']; }
if(function_exists('imagefilter')){
imagefilter($img, IMG_FILTER_GAUSSIAN_BLUR);
}header( 'Cache-Control: no-store, no-cache, must-revalidate' ); header( 'Cache-Control: post-check=0, pre-check=0', false ); header( 'Pragma: no-cache' ); header( 'Content-type: image/png' ); imagepng($img); imagedestroy($img);
THE END
Eh! Verificarea! :P Era sa uit... Hai ca-i simplu!
In fisierul in care se verifica datele trimise pe POST va trebui sa deschidem sesiunea folosind session_start();, dupa care va trebui sa verificam ca datele primite de la formular coincid cu cele salvate in sesiune, adica, in cazul nostru, ceva de genul:
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($_POST['myCaptcha'] == $_SESSION['myCaptcha']){
// se proceseaza restul datelor
}else{
// Wrong Code! Try Again or Go Away!
}
}<img src="show_code.php" alt="myCaptcha" onclick="javascript:this.src += '?';" />