Crear CAPTCHA con PHP

Captcha es una palabra aleatoria y en ocasiones distorsionada mostrada como imagen que se utiliza para evitar que los robots accedan a determinadas web. Este tipo de verificación es utilizada por los programadores para evitar el spam en lo blogs por ejemplo.

captcha.gif

La idea básica para crear un Captcha es generar primero un texto aleatorio, luego basado en este texto generamos una imagen la cual se muestra al usuario, finalmente se compara el texto ingresado por el usuario con la palabra aleatorio generada.

Generar el Captcha
La primero es crear una imagen con un texto aleatorio, para ello un archivo llamado captcha.php el cual creará dinámicamente el texto. Para ello creamos una función llamada randomText que se encarga de generar una cadena de texto aleatorio, acepta un parámetro el cual le indica cuantos caracteres puede tener el texto generado.

// archivo: captcha.php
function randomText($length) {
    $pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
    for($i=0;$i<$length;$i++) {
      $key .= $pattern{rand(0,35)};
    }
    return $key;
}
[/php]

Lo siguiente es crear una variable de sesión para guardar el texto generado, luego de ello tomamos una imagen que contiene el fondo para el captcha en nuestro caso la imagen es bgcaptcha.gif, luego creamos el texto sobre esta imagen para luego mostrarla en el navegador como imagen enviándole un header indicando el tipo de archivo.
[php]
session_start();
$_SESSION['tmptxt'] = randomText(8);
$captcha = imagecreatefromgif("bgcaptcha.gif");
$colText = imagecolorallocate($captcha, 0, 0, 0);
imagestring($captcha, 5, 16, 7, $_SESSION['tmptxt'], $colText);
header("Content-type: image/gif");
imagegif($captcha);

Crear el formulario para verificar el Captcha
Lo siguiente es mostrar la imagen generado para que el usuario pueda leerlo e ingresar el texto en el formulario para ser verificado. Naturalmente esta verificación será parte de un formulario mucho mas grande pero solo incluimos un campo para propósitos de ejemplo. Esto lo incluimos en el archivo captchademo.php, note que al incluir la imagen hemos colocado la ruta al php que genera la imagen.

Ingresar el texto mostrado en la imagen <br>
<form action="captchademo.php" method="post">
  <img loading="lazy" src="captcha.php" width="100" height="30"><br>
  <input name="tmptxt" type="text"><br>
  <input name="btget" type="submit" value="Verificar Codigo">
  <input name="action" type="hidden" value="checkdata">
</form>

Verificar el texto Ingresado
Lo siguiente es verificar el texto ingresado en el formulario y compararlo con la variable $_SESSION[‘tmptxt’] que contiene el texto generado aleatoriamente. Para ello verificamos que se haya enviado el formulario y luego comparamos el texto ingresado con el texto que tenemos en la variable de sesión.

session_start();
if ($_POST['action'] == "checkdata") {
	if ($_SESSION['tmptxt'] == $_POST['tmptxt']) {
		echo "Bienvenido";
	} else {
		echo "Inténtalo nuevamente";
	}
	exit;
}

Ideas Adicionales
Nuestro ejemplo es sencillo, pero se puede mejorar esto por ejemplo dibujando lineas aleatorios con ángulos aleatorios sobre el texto, también se puede dibujar el texto con una inclinación aleatorio, también se pueden colocar cada letra con distintos ángulos de rotación y color. Con estos adicionales pueden lograr un Captcha mucho mas consistente y seguro.

Pueden ver el ejemplo funcionando en captchademo.php y también pueden descargar los archivos con las fuentes para que lo descarguen y prueben.

Comentarios Total 156 comentarios

Miguel
Publicado: 17/09/2012 5:26 pm

Gracias! si funcionó despues de todo
no se porque pero la función que me retorna el key hacía que la imagen no apareciera, pero lo cambié por otra y si funcionó perfectamente :D

El-vividor
Publicado: 21/10/2012 4:43 am

unijimpe, disculpa, pero me he bajadop tu script, y todo anda bien, todo excepto que no es tan seguro como parece, pues el spam me sigue llegando, aunque ya no con tanta frecuencia como antes, lo se por que por cada formulario que se envia recibo una copia en mi correo, a que se podria deber esto¿?

Jorge
Publicado: 05/12/2012 12:15 am

Excelente, no estoy pensando en colocarlo actualmente pero quería saber como funcionaba para un futuro y este ejemplo sencillo me lo ha explicado de mil maravillas. Gracias.

Carlos
Publicado: 16/04/2014 10:28 am

Oye muchas gracias!
Sencillo y eficiente tu código

GABRIEL RINCON
Publicado: 04/12/2014 10:57 am

hay un error en las nuevas versiones de php.

Toca inicializar la variable $key

function randomText($length) {
$pattern = «1234567890abcdefghijklmnopqrstuvwxyz»;
$key=null;//Línea insertada
for($i=0;$i<$length;$i++) {
$key .= $pattern{rand(0,35)};
}
return $key;
}

Belkys
Publicado: 12/01/2015 1:54 pm

Excelente!!.

En mi caso, tenía un formulario ya construído con códigos html y php, así que sólo inserté el código, reacomodé la secuencia y wala!… funcionó casi perfecto.. a excepción de un warning con el session_start(); …

Warning: Cannot send session cache limiter – headers already sent … etc etc..

Para evitarlo solamente debes colocar el session_start(); en la linea 1 del documento, es decir, arriba de cualquier codigo html, php o cualquier otro código que tengas en tu página.

Saludos.

 

Comentar

En este blog los comentarios están moderados, serán mostrados cuando el administrador los apruebe. Por favor, evita comentarios ofensivos u obscenos por que no serán aprobados.
Si deseas publicar código fuente debes hacerlo entre las etiquedas <code> y </code>, además debes reemplazar los carácteres < por &lt; y > por &gt;.

(Requerido)

(Requerido, no será publicado)

(Requerido)

(Tags aceptados: <a> <em> <strong> <code> <ul> <li>)