Tutorial: Sistema Captcha con PHP
Cómo hemos ido comentando desde hace buen tiempo atrás, existen varios métodos para bloquear el spam de nuestras páginas web; por ejemplo, uno de los métodos que más agrada es utilizando Akismet, un servicio web anti spam, transparente al usuario.
Sin embargo, hay veces que Akismet no cubre las expectativas ó simplemente, hay aplicaciones en que no puede utilizarse. Por ello, vamos comentar otro método para impedir el acceso de los robots a nuestro sistema, esta vez, con la creación de un Captcha con PHP.
Esta es la traducción de un artículo recientemente publicado en fuzzyopinions, del cual, su simpleza y funcionamiento y diseño final me han agradado bastante. El resultado final del Captcha lo pueden observar en la siguiente imagen:

Cómo sabrán un captcha es solicitar al usuario que escriba los caracteres que aparecen en una imagen dentro de un campo de texto. Si lo hace correctamente tendrá acceso, de lo contrario, se le pedirá que vuelva a escribir el código, indicándole que lo que ha escrito esta errado.
7 pasos para crear un captcha
Estos son los siete pasos básicos para generar un sistema Captcha:
- Generar un código aleatorio
- Añadir el código a una cookie, variable de sesión ó base de datos que será recuperada desde la siguente página
- Escribir el texto dentro de una imagen
- Mostrar la imagen al usuario que quiera acceder al recurso
- Proveer de un formulario, donde el usuario ingrese el código y lo envíe
- Verificar el código de la clave enviada (en el paso 2)
- Si el código es correcto, se permite el acceso
A continuación veremos el código necesario para crear nuestro captcha.
Generando y almacenando el código
Cómo mencionamos en el primer paso, el texto del código debe ser aleatorio. Hay varias maneras de conseguir esto, por lo que en este paso podemos sentirnos libres de experimentar, pero eso si, lo que hagamos debe de cumplir dos cosas: 1) Recuperar un valor que cambie constantemente y 2) Cifrar ese valor.
Un valor que cambia constantemente puede ser, por ejemplo, la fecha y hora del servidor, para ello, nos serviremos de las funciones microtime( ) y mktime( ) de PHP. Una vez con el valor totalmente aleatorio en nuestras manos, lo cifraremos con la función md5() de PHP. Finalmente (fíjense en la última línea del código), almacenaremos el valor en una variable de sesión.
<?php
// Iniciamos sesión
session_start( );
// Indicamos el tamaño de nuestro captcha, puede ser aleatorio para mayor seguridad
$captchaTextSize = 7;
do {
// Generamos un string aleatorio y lo encriptamos con md5
$md5Hash = md5( microtime( ) * mktime( ) );
// Eliminamos cualquier caracter extraño
preg_replace( ‘([1aeilou0])’, “”, $md5Hash );
} while( strlen( $md5Hash ) < $captchaTextSize );
// necesitamos sólo 7 caracteres para este captcha
$key = substr( $md5Hash, 0, $captchaTextSize );
// Guardamos la clave en la variable de sesión. La clave esta encriptada.
$_SESSION[’key’] = md5( $key );
?>
Mostrando el código aleatorio en la imagen Captcha
Una vez generado el código captcha y almacenado correctamente, procederemos a recuperarlo y mostrarlo al usuario. Para el manejo de la imagen utilizaremos la librería GD.
<?php
// almacenamos la imagen base, el background.
$captchaImage = imagecreatefrompng( “images/captcha.png” );
/*
Seleccionamos un color de texto. Cómo nuestro fondo es un verde agua, escogeremos un cólor verde para el texto. El color del texto es, preferentemente, el mismo que el del background, aunque un poco más oscuro para poder distnguirlo.
*/
$textColor = imagecolorallocate( $captchaImage, 31, 118, 92 );
/*
Seleccionamos un color para las líneas que queremos se dibujen en nuestro captcha. En este caso usaremos una mezcla entre verde y azul
*/
$lineColor = imagecolorallocate( $captchaImage, 15, 103, 103 );
?>
Ya hemos seleccionado los colores, ahora queremos mostrar algunas líneas que incrementen la dificultad, para que los robots (spam) no lean nuestro código (texto aleatorio).
<?php
// recuperamos el parametro tamaño de imagen
$imageInfo = getimagesize( “images/captcha.png” );
// decidimos cuantas líneas queremos dibujar
$linesToDraw = 10;
// Añadimos las líneas de manera aleatoria
for( $i = 0; $i < $linesToDraw; $i++ ) {
// utilizamos la función mt_rand()
$xStart = mt_rand( 0, $imageInfo[ 0 ] );
$xEnd = mt_rand( 0, $imageInfo[ 0 ] );
// Dibujamos la linea en el captcha
imageline( $captchaImage, $xStart, 0, $xEnd, $imageInfo[1], $lineColor );
}
?>
Finalmente, escribimos nuestro código en la imagen y la mostramos en la pantalla. Comenzaremos con una imagen de fondo pre generada. Este método, puede fácilmente permitirnos incluir docenas de fondos adicionales, seleccionados al azar, o aún, para hacerlo más complejo, podríamos generarlo nosotros mismos, dentro del captcha.
Para escribir nuestro captcha usaremos la función imagettftext(), la cual se caracteriza por escribir un texto sobre una imagen usando fuentes TrueType. En este caso, utilizaremos la fuente BitStream Vera Sans Bold, que es una fuente Open Source que podemos copiar y redistribuir libremente. Ahora bien, si queremos podemos utilizar cualquier otra fuente, ó aún mejor, mezclar fuentes al azar para hacer más difícil que los robots lean nuestra imagen.
<?php
/*
Escribimos nuestro string aleatoriamente, utilizando una fuente true type. En este caso, estamos utilizando BitStream Vera Sans Bold, pero podemos utilizar cualquier otra.
*/
imagettftext( $captchaImage, 20, 0, 35, 35, $textColor, “fonts/VeraBd.ttf”, $key );
/* Mostramos nuestra imagen. Preparamos las cabeceras de la imagen previniendo que no se almacenen en la cache del navegado
*/
header ( “Content-type: image/png” );
header(”Cache-Control: no-cache, must-revalidate”);
header(”Expires: Fri, 19 Jan 1994 05:00:00 GMT”);
header(”Pragma: no-cache”);
imagepng( $captchaImage );
?>
Ahora que ya tenemos nuestro captcha elaborado, el paso final es crear el formulario que interactúe con el usuario.
Incluyendo el Captcha en la página web
Para verificar el correcto funcionamiento de nuestro captcha, necesitamos crear un formulario que permita al usuario ver el código, escribirlo en un campo de texto y enviarlo pulsando un botón. Esto ya todos lo debemos de conocer, por lo que no nos explayamos en este punto.
<img src=”captcha.php” border=”0″ />
<form name=”captcha-form” method=”POST” action=”captcha-verify.php”>
<input type=”text” name=”code” width=”25″ />
<input type=”submit” name=”submit” value=”submit” />
</form>
Ahora bien, asumiendo que el formulario ha sido enviado, deberemos ser capaces de verificar el código enviado. Por ejemplo podemos utilizar un script PHP similar a este.
<?php
session_start( ); // iniciamos sesión
/*
Encriptamos la clave pasada por el formulario y luego la comparamos con el valor del captcha (almacenado en la variable de sesión)
*/
if( md5( $_POST[ ‘code’ ] ) != $_SESSION[ ‘key’ ] ) {
echo “Usted no ha escrito el código de verificación correctamente. Por favor, intentelo de nuevo!”;
} else {
echo "Usted ha escrito el código correctamente. Bienvenido...";
}
?>
Eso es todo. Desde luego, hay mucho que se podría hacer para personalizar un Sistema Captcha, hacerlo más complejo e incluirlo en nuestros sitios web. Estas son algunas ideas:
- Combinar palabras para hacerlo semilegible y dificultar a los robots que lean la imagen. Esto se podría hacer utilizando dos archivos de donde se recuperen los textos.
- Girar el texto al azar y jugar con el espacio entre las letras. Aunque hay que tener cuidado de no hacerlo muy enrevesado, tanto que nuestros propios usuarios no puedan entenderlo.
- Cambie la ubicación del texto en la pantalla. En nuestro caso, el texto siempre aparece en un mismo punto, pero podríamos cambiar su ubicación al azar.
Espero que este mini tutorial sobre la creación de un Sistema Captcha con PHP les haya sido de ayuda, aunque sea mostrando los conceptos básicos de su creación.
Ejemplo | Resultado Final
Descargar | Código Fuente





crear un weblog es mi trabajo de programacion de fin de ciclo esto creo que me va ha ayudar y aun necesito mas ayuda para hacerlo lo mejor que pueda
- responder
Enviado por Wilfredo Benitez (no verificado) el Lun, 04/09/2007 - 12:28.Excelente lo tuyo, ya lo estoy implementando...
saludos.....
- responder
Enviado por Anonymous (no verificado) el Mié, 03/05/2008 - 18:13.Muy buen tutorial gracias!
- responder
Enviado por gonzalo (no verificado) el Mié, 05/09/2007 - 14:21.hola,revisé el tutorial me funcion
- responder
Enviado por claudia (no verificado) el Mié, 07/11/2007 - 13:23.Ha sido de gran ayuda
- responder
Enviado por miguel (no verificado) el Mié, 07/18/2007 - 21:14.Funciona bien,pero a mi me da un problema que aunque pongan el codigo mal lo sige enviando el formulario de correo Un saludo
- responder
Enviado por AuRoN (no verificado) el Lun, 08/13/2007 - 06:46.En una web me funcionaba bien pero luego lo probe en otra y hac
- responder
Enviado por Antoni Vila (no verificado) el Sáb, 08/18/2007 - 06:16.podrias renombrar la variable local $key a $key2 por ejemplo y asi ya no tendr
- responder
Enviado por beto barbosa (no verificado) el Vie, 09/28/2007 - 16:43.Muy buen tutorial.He detectado un pequeño error, pero no veo como solucionarlo.Si definimos $captchaTextSize = 7se supone que la longitud de la cadena deber
- responder
Enviado por Alex (no verificado) el Jue, 10/04/2007 - 04:19.por si no sabias a
- responder
Enviado por kolob (no verificado) el Jue, 12/27/2007 - 13:58.Estoy usando esta tecnolog
- responder
Enviado por Sherryl (no verificado) el Vie, 02/01/2008 - 09:31.Deja tu comentario