Explicando los captchas

01.sep 2006 Envía un trackback

Como comentaba en la entrada anterior, he decidido meter captchas en los comentarios de las anotaciones y fotos para prevenir todo el spam que estaba llegando últimamente al blog, no quiero contabilizar el tiempo que he pasado borrando mierda a la vuelta de vacaciones.

Los captcha son una prueba-desafío para determinar cuando el usuario es humano o no, consiste en mostrar una imagen con un texto distorsionado de forma que una máquina no sea capaz de comprender e introducir las letras de forma correcta sin embargo un humano sí podría hacerlo.

La programación en PHP es sencilla siempre y cuando entendamos la sintáxis de algunas funciones LibGD. Básicamente se trata de, dada una fuente (truetype en este caso) y una imagen de fondo (cuanto menos uniforme mejor) crear una nueva imagen con un texto aleatorio. La fuente se llama captcha.ttf, el fondo fnd_captcha.jpg y la página encargada de generar la imagen es la siguiente (captcha.php):
<?php
session_start();

$str = "";
for ($i = 0; $i < 4; $i++) // Generamos un texto aleatorio de 4 caracteres
{
   $str .= chr(rand(97, 122));
}
$_SESSION['captcha'] = $str;

// Dimensiones de la imagen
$imgX = 90;
$imgY = 23;
$image = imagecreatefromjpeg("./fnd_captcha.jpg");
// Fondos y colores (de borde y texto)
$backgr_col = imagecolorallocate($image, 238,239,239);
$border_col = imagecolorallocate($image, 0,0,0);
$text_col = imagecolorallocate($image, 52,99,255);

imagerectangle($image, 0, 0, 89, 29, $border_col);

$font = "./captcha.ttf"; // La fuente ttf
$font_size = 14;
$angle = 15;
$box = imagettfbbox($font_size, $angle, $font, $str);
$x = (int)($imgX - $box[4]) / 2;
$y = (int)($imgY - $box[5]) / 2;
imagettftext($image, $font_size, $angle, $x, $y, $text_col, $font, $str);

header('Content-type: image/png');
imagepng($image);
imagedestroy ($image);
?>
 
La página nos devuelve la imagen, osea que la usaremos como fuente del tag img, algo así: <img src="captcha.php" alt="Captcha" /> Además de la imagen tenemos una variable $_SESSION['captcha'] con el valor de la cadena generada, que nos servirá para saber si el usuario teclea lo que ve o no (imaginando que el input del formulario se llamase captcha_form):
<?php
   if($_SESSION[captcha]==$_POST[captcha_form])
      $correcto=1;
   else
      $correcto=0;
?>
 
Imagino que se entiende bien, pero ni es suficiente ni funciona (y esto es lo que me ha traido mosqueado). Obviamente los robots spammers no van a abrir una sesión, con lo que no generan $_SESSION[captcha], tampoco rellenarán $_POST[captcha_form] así que la condición se cumple y se asume el comentario como correcto (¡estúpido de mi!). Un pequeño parche que por el momento está funcionando es agregar otro condicionante:
<?php
   if($_SESSION[captcha]==$_POST[captcha_form] AND
      strlen($_SESSION[captcha])!='0' AND
      strlen($_POST[captcha_form])!='0')
         $correcto=1;
   else
         $correcto=0;
?>
 
El funcionamiento es básico y seguro que está explicado con más chicha en miles de sitios, así que esta ha sido mi pequeña aportación al mundo-captcha. ¿Alguien se anima a mejorarlo?.

Actualización
Juanjo ha enviado un ejemplo de mi captcha a una dirección (http://captcha.megaleecher.net/) en la que tratan de descifrar el texto usando PHP, el resultado ha sido satisfactorio, ya que no han logrado 'leer' la clave.
captcha blog

Comentarios
Gravatar krs@01.09.2006, 'Re: Explicando los captchas'

Ey, muy bien!, desde luego es mucho más efectivo que el antiguo sistema de control por ip o por contenido. Ya sabes que mi sistema de "captcha's" no es ni mucho menos dinámico, cómo es lo habitual, pero tampoco creo que ningún spammer pierda más de dos segundos en intentar spammear mi web, y me hacía ilusión meter palabras con algún sentido, y de momento funciona!... :D

Un abrazo socio, espero que la vuelta a la vida cotidiana sea lo más leve posible.

Gravatar r0sk@01.09.2006, 'Re: Explicando los captchas'

Tu captcha está genial, es más, mucha gente lo hace así, creando un gran array con palabras con cierto sentido y visualizando una al azar. Dependiendo del tamaño del array habrá más o menos probabilidades de que te hagan la faena, pero como tú dices, no creo que nadie pierda tiempo con un simple blog.

¡Saludos co!.


Escribe tu comentario
 
 
Guardar datos
Escribe tu comentario:
captcha


Intenta que tu comentario sea interesante y con información relevante al tema de la entrada. BBCodes disponibles: [url=http://direccion]texto[/url], negrita: [b]texto[/b], itálica: [i]texto[/i], subrayada: [u]texto[/u]. Para mencionar o citar a alguien (quote): [cita]texto[/cita]