Laboratorio: ejemplo de CAPTCHA
El otro dÃa và en Rapidshare un ejemplo de CAPTCHA que parecÃa fácil de desarrollar. Se trata de las letras (tres en este caso), giradas ángulos aleatorios, pero no demasiado para que se pueda leer con facilidad, sobre un fondo de letras de tonalidad parecida, de menor tamaño y también giradas aleatoriamente.
Un ejemplo dinámico es el siguiente:
El método es muy sencillo, usamos una cadena de texto con todas las letras que queremos que aparezcan, para poder acceder aleatoriamente a cada una de ellas. Después nos crearemos el fondo de la imagen, siendo un gris claro y unas letras pequeñas, de un gris un poco más oscuro sobre ellas, que llenan toda la imagen. Y por último, creamos las tres letras del CAPTCHA para mostrarlas en el centro de la imagen y de un tamaño considerable.
En este caso he cogido la fuente de daFont, pero se puede usar la que se quiera. Yo recomiendo usar alguna que esté distorsionada para que la lectura para nosotros no presente complicaciones, pero si para algún proceso automático.
El script serÃa el siguiente, teniendo en cuenta que no se trata el almacenamiento en sesión de las letras del CAPTCHA para luego poder compararlas.
<?php
// Juego de letras para usar
$letras = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Configuración tamaño imagen y tamaño fuente
$ancho_caja = 200;
$alto_caja = 100;
$tam_letra = 16;
$tam_letra_grande = 60;
// angulo máximo que rota (izq y der) cada letra
$angmax = 20;
// Establecer el tipo de contenido
header("Content-type: image/png");
// Creamos una imagen
$im = imagecreate($ancho_caja, $alto_caja);
// Creo el color del texto, del texto del fondo y del fondo de la imagen
$gris = ImageColorAllocate($im, 200, 200, 200);
$colorLetra = ImageColorAllocate($im, 175, 175, 175);
$colorLetraFondo = ImageColorAllocate($im, 180, 180, 180);
// tipo de letra obtenido en dafont.net
$fuente = './Hotel Coral Essex.ttf';
// Calculo el número de lÃneas que entran
$caja_texto = imagettfbbox($tam_letra, 0, $fuente , $letras);
$alto_linea = abs($caja_texto[7]-$caja_texto[1]);
$num_lineas = intval($alto_caja / $alto_linea)+1;
// Dibujo las letras del fondo
// Cada letra de escribe de una en una para poder
// darle una rotación independiente al resto
$pos = 0;
for ($i = 0; $i<$num_lineas; $i++) {
$x = 0;
for ($j = 0; $j<30; $j++) {
$texto_linea = $letras[rand(0, strlen($letras)-1)].' ';
$caja_texto = imagettfbbox($tam_letra, 0, $fuente , $texto_linea);
imagettftext($im, $tam_letra, rand(-$angmax, $angmax), $x, $alto_linea*$i, $colorLetraFondo, $fuente , $texto_linea);
// Posicion x de la siguiente letra
$x += $caja_texto[2] - $caja_texto[0];
}
}
// Escribo las tres letras del CAPTCHA
$res = $letras[rand(0, strlen($letras)-1)];
$ang1 = rand(-$angmax, $angmax);
$caja_texto = imagettfbbox($tam_letra_grande, $ang1, $fuente , $res);
$y1 = abs($caja_texto[7]-$caja_texto[1]);
$x1 = abs($caja_texto[2]-$caja_texto[0]);
$res .= $letras[rand(0, strlen($letras)-1)];
$ang2 = rand(-$angmax, $angmax);
$caja_texto = imagettfbbox($tam_letra_grande, $ang2, $fuente , $res[1]);
$y2 = abs($caja_texto[7]-$caja_texto[1]);
$x2 = abs($caja_texto[2]-$caja_texto[0]);
$res .= $letras[rand(0, strlen($letras)-1)];
$ang3 = rand(-$angmax, $angmax);
$caja_texto = imagettfbbox($tam_letra_grande, $ang3, $fuente , $res[2]);
$y3 = abs($caja_texto[7]-$caja_texto[1]);
$x3 = abs($caja_texto[2]-$caja_texto[0]);
imagettftext($im, $tam_letra_grande, $ang1, ($ancho_caja/2)-(($x1+$x2+$x3)/2), $y1+($alto_caja-$y1)/2, $colorLetra, $fuente , $res[0]);
imagettftext($im, $tam_letra_grande, $ang2, ($ancho_caja/2)-(($x1+$x2+$x3)/2)+($x1), $y2+($alto_caja-$y2)/2, $colorLetra, $fuente , $res[1]);
imagettftext($im, $tam_letra_grande, $ang3, ($ancho_caja/2)-(($x1+$x2+$x3)/2)+($x1+$x2), $y3+($alto_caja-$y3)/2, $colorLetra, $fuente , $res[2]);
imagepng($im);
imagedestroy($im);
imagedestroy($im2);
?>
Un ejemplo lo podéis ver en la misma imagen que aparece arriba, ya que es dinámica y se modifica al recargar la página.
Debido a la decepción que me estoy llevando con el Zend Framework, aunque aún tengo esperanzas en que vaya mejorando, he tenido que buscar otras librerÃas PHP para crear PDF. Una que he encontrado que me está gustando bastante (por ahora) es FPDF, una librerÃa que exporta a PDF sin necesidad de PDFLib (la cual es de pago). Lo bueno que tiene tambien es que es gratuita, se puede usar libremente y modificar según nuestras necesidades.
Server2Go es un servidor web completo y portable, el cual podremos tener instalado en CDROMs o unidades USB.