Text Resizer Text Resizer
July 30th, 2010
You're browsing: Scriptmatico.Com » PHP, Scripts » Captcha Basado en click – Un Captcha totalmente diferente

Captcha Basado en click – Un Captcha totalmente diferente

Posted on Oct 03 in PHP, Scriptsby adminPrintText Resizer Text Resizer

En este tutorial, el objetivo es hacer un "click" en el captcha para validar que el formulario no haya sido rellenado por un robot.

Vamos a necesitar dos imágenes:

La Imagen de seguridad:

La imagen de la máscara de Captcha:

A continuación pondre el codigo explicado:

PHP:
  1. <?php
  2.  
  3.   // iniciamos la session
  4.  
  5.   // declaramos nuestras variables
  6.   $width = 180;
  7.   $height = 90;
  8.   $blob_width = 40;
  9.   $blob_height = 40;
  10.  
  11.   // creamos nuestra imagen
  12.   $image = imagecreatetruecolor($width, $height);
  13.  
  14.   //color background de la imagen
  15.   $white = imagecolorallocate($image, 230, 230, 230);
  16.   $red  = imagecolorallocate($image, 255, 0, 0);
  17.   $blue  = imagecolorallocate($image, 0, 0, 230);
  18.  
  19.   // llenamos el contenedor de la imagen
  20.   imagefilledrectangle($image, 0, 0, $width, $height ,$white);
  21.  
  22.  
  23.   // creamos el background de espirales para nuestra imagen
  24.  
  25.   $theta    = 1;
  26.   $thetac   = 7;
  27.   $radius   = 16;
  28.   $circles  = 20;
  29.   $points   = 32;
  30.  
  31.   for ($i = 0; $i <($circles * $points) - 1; $i++)
  32.   {
  33.     $theta = $theta + $thetac;
  34.     $rad = $radius * ($i / $points );
  35.     $x = ($rad * cos($theta)) + $x_axis;
  36.     $y = ($rad * sin($theta)) + $y_axis;
  37.     $theta = $theta + $thetac;
  38.     $rad1 = $radius * (($i + 1) / $points);
  39.     $x1 = ($rad1 * cos($theta)) + $x_axis;
  40.     $y1 = ($rad1 * sin($theta )) + $y_axis;
  41.     imageline($image, $x, $y, $x1, $y1, $blue);
  42.     $theta = $theta - $thetac;
  43.   }
  44.  
  45.   // obtenemos la posicion de nuestro circulo aleatoriamente
  46.   $x_axis = rand($blob_width, $width) - ($blob_width / 2);
  47.   $y_axis = rand($blob_height, $height)  - ($blob_height / 2);
  48.  
  49.   // dibujamos el circulo
  50.   imagefilledellipse ($image, $x_axis, $y_axis, $blob_width, $blob_height, $red);
  51.  
  52.   // creamos la imagen de mascara
  53.   $mask_image = imagecreatetruecolor($width, $height);
  54.  
  55.   // escogemos el color de nuestro background y color de circulo para nuestra mascara
  56.   $mask_white = imagecolorallocate($mask_image, 255, 255, 255);
  57.   $mask_red  = imagecolorallocate($mask_image, 255, 0, 0);
  58.  
  59.   // llenamos la imagen mascara con nuestro background
  60.   imagefilledrectangle($mask_image, 0, 0, $width, $height ,$mask_white);
  61.  
  62.   // dibujamos el circulo en nuestra mascara
  63.   imagefilledellipse ($mask_image, $x_axis, $y_axis, $blob_width, $blob_height, $mask_red);
  64.  
  65.   // escribimos la imagen en el buffer
  66.   ob_start();
  67.   imagepng($mask_image);
  68.   $mask_image_data = ob_get_contents()// recibimos los datos y limpiamos el buffer
  69.  
  70.   // convertimos la imagen a Base64
  71.   $mask_image_data_b64base64_encode($mask_image_data);
  72.  
  73.   // guardamos los datos en nuestra variable del servidor
  74.  $_SESSION['captcha_image_code'] = $mask_image_data_b64;
  75.  
  76.  
  77.   // Enviamos las cabeceras del contenido
  78.   header('Content-type: image/jpeg');
  79.   header('Cache-control: no-cache');
  80.  
  81.   // lanzamos la imagen al navegador
  82.   imagejpeg($image);
  83.  
  84.   imagedestroy($image);
  85.  
  86.   ?>

Ahora el formulario:

HTML:
  1. <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data"> 
  2.       <p>Name<br/><input type="text" name="name" /></p> 
  3.       <p>Comment<br/><textarea name="message"></textarea></p>
  4.       <p>
  5.         Click the Red Circle to continue:<br/>
  6.         <input type='image' name='submit' src='captcha.php' alt='Captcha Security'  />
  7.       </p>
  8.   </form>

Por ultimo la validacion:

PHP:
  1.  
  2.   if(isset($_POST['submit_x']) && isset($_POST['submit_y'])) { 
  3.  
  4.       if(!empty($_POST['name']) && !empty($_POST['message'])) { 
  5.  
  6.         // retrive the image captcha data
  7.         $data = base64_decode($_SESSION['captcha_image_code']);
  8.  
  9.         $captcha_image = imagecreatefromstring($data);
  10.         $x = $_POST['submit_x'];
  11.         $y = $_POST['submit_y'];
  12.  
  13.         // get the pixel color of the clicked x and y coordinate
  14.         $rgb = imagecolorat($captcha_image, $x, $y);
  15.         $color_tran = imagecolorsforindex($captcha_image, $rgb);
  16.  
  17.         // check if the color is red and red only
  18.         $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;
  19.  
  20.         if($captcha_ok) { 
  21.  
  22.           $result = "Thank you for submitting your comment.";           
  23.  
  24.         } else { 
  25.  
  26.           $result = "Please make sure you click the red circle!"
  27.  
  28.         } 
  29.  
  30.       } else { 
  31.  
  32.           $result = "Please fill out the entire form."
  33.  
  34.       } 
  35.  
  36.   }

Un cambio adicional aquí es recuperar la imagen de la máscara de la sesión y volver a poner esa imagen de un objeto y luego obtener el color del píxel de X e Y.

Para ello, primero tenemos que recuperar la imagen de la máscara de la sesión y luego descifrar como se muestra a continuación:

PHP:
  1. // retrive the image captcha data
  2.   $data = base64_decode($_SESSION['captcha_image_code']);

A continuación, convertirlo de nuevo en una imagen del objeto utilizando la funcion ImageCreateFromString().

PHP:
  1. $captcha_image = imagecreatefromstring($data);

Luego recuperar la coordenadas X e Y desde el primer clic que el usuario envía, junto con el color del píxel usando imagecolorsforindex (). Nos aseguramos de que sólo se obtiene un color rojo y nada más.

PHP:
  1. // obtenemos el  color del pixel que fue clickeado con las coordenas "x" y "y"
  2.   $rgb = imagecolorat($captcha_image, $x, $y);
  3.   $color_tran = imagecolorsforindex($captcha_image, $rgb);
  4.  
  5.   // verificamos que el color sea solo rojo
  6.   $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;

Despues de todo esto el formulario nos quedaria asi:

HTML:
  1. <?php 
  2. session_start();
  3.  
  4. if(isset($_POST['submit_x']) && isset($_POST['submit_y'])) { 
  5.  
  6.     if(!empty($_POST['name']) && !empty($_POST['message'])) { 
  7.  
  8.       // retrive the image captcha data
  9.       $data = base64_decode($_SESSION['captcha_image_code']);
  10.  
  11.       $captcha_image = imagecreatefromstring($data);
  12.       $x = $_POST['submit_x'];
  13.       $y = $_POST['submit_y'];
  14.  
  15.       // get the pixel color of the clicked x and y coordinate
  16.       $rgb = imagecolorat($captcha_image, $x, $y);
  17.       $color_tran = imagecolorsforindex($captcha_image, $rgb);
  18.  
  19.       // check if the color is red and red only
  20.       $captcha_ok = ($color_tran['red'] == 255 && $color_tran['green'] == 0 && $color_tran['blue'] == 0 && $color_tran['alpha'] == 0) ;
  21.  
  22.       if($captcha_ok) { 
  23.  
  24.         $result = "Thank you for submitting your comment.";           
  25.  
  26.       } else { 
  27.  
  28.         $result = "Please make sure you click the red circle!"
  29.  
  30.       } 
  31.  
  32.     } else { 
  33.  
  34.         $result = "Please fill out the entire form."
  35.  
  36.     } 
  37.  
  38. } 
  39. ?>
  40.  
  41. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  42. <html xmlns="http://www.w3.org/1999/xhtml"> 
  43. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  44. <title>Captcha Demo</title> 
  45. </head> 
  46.  
  47.  
  48. <?php if(!empty($result)) echo "<div style='color:#990000; margin-bottom: 20px;'>" . $result . "</div>"; ?> 
  49.  
  50. <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data"> 
  51.     <p>Name<br/><input type="text" name="name" /></p> 
  52.     <p>Comment<br/><textarea name="message"></textarea></p>
  53.     <p>
  54.       Click the Red Circle to continue:<br/>
  55.       <input type='image' name='submit' src='captcha.php' alt='Captcha Security'  />
  56.     </p>
  57. </form> 
  58.  
  59. </body> 
  60. </html>

Ahora puedes implementarlo en tu web, puedes cambiar los colores y jugar un poco con esta validacion, veras que no es muy dificil.

Post to Twitter


  • No Related Post

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Back to Top
[x] Cerrar
E-mail