Es un tipo de captcha que dificulta bastante la tarea de ser reconocido automáticamente por programas.
¿Cómo funciona?
El método DelaRub consiste en utilizar los mismos colores para las letras que para el fondo de manera que sea tarea complicada separar las letras del fondo.
Para ello, utiliza como fondo de captcha un degradado de color, y encima las letras con el color opuesto al de ese lugar del degradado. Si ahora no se ha entendido, con la explicación será mas sencillo.
Programando un captcha DelaRub
Vamos a partir de un simple captcha que hemos programado, y que no tiene casi seguridad.
Código PHP:
<?php
function textoAleatorio($largo) {
// Todas las letras posibles
$letras = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ";
// Un loop para hacer $largo letras
for ($i = 1; $i <= $largo; $i++) {
// Obtenemos un numero aleatorio entre 0 y el numero de letras
$num = rand(0, strlen($letras) - 1);
// Y añadimos la letra segun el numero
$final .= $letras{$num};
}
// Devolvemos el resultado
return $final;
}
// 8 Letras en el captcha
$cantidadLetras = 8;
// Creamos una cadena aleatoria
$cadena = textoAleatorio($cantidadLetras);
// Creamos una imagen y asignamos colores
$captcha = imagecreate(100, 35);
$colorBlanco = imagecolorallocate($captcha, 255, 255, 255);
$colorNegro = imagecolorallocate($captcha, 0, 0, 0);
// Imprimimos la cadena en la imagen
imagestring($captcha, 5, 10, 10, $cadena, $colorNegro);
// Mostramos el captcha
header("Content-type: image/png");
imagepng($captcha);
?>
Código PHP:
// Imprimimos la cadena en la imagen
imagestring($captcha, 5, 10, 10, $cadena, $colorNegro);
Código PHP:
// Imprimimos la cadena en la imagen, con alturas aleatorias
for ($i = 1; $i <= $cantidadLetras; $i++) {
imagestring($captcha, 5, 10 * $i, rand(1, 20), $cadena{$i - 1}, $colorNegro);
}
Código PHP:
function delarubCaptcha($captcha, $rgbInicial, $rgbFinal) {
// Esta funcion crea un fondo degradado y adapta las letras
// para que sean legibles con los mismos colores que el fondo
// de manera que un bot no puede eliminar el fondo.
// Estructura de los rgb -> R|G|B
// Dividimos el string $rgbInicial para obtener un array con los 3 colores
$rgbIniArray = explode("|", $rgbInicial);
// Y los asignamos
$rInicial = $rgbIniArray[0];
$gInicial = $rgbIniArray[1];
$bInicial = $rgbIniArray[2];
// Igual que antes
$rgbFinArray = explode("|", $rgbFinal);
$rFinal = $rgbFinArray[0];
$gFinal = $rgbFinArray[1];
$bFinal = $rgbFinArray[2];
// Obtenemos el ancho y alto de la imagen
$ancho = imagesx($captcha);
$alto = imagesy($captcha);
// Calculamos cuanto R bajar en cada linea
$difRojo = $rFinal - $rInicial;
$difRojo = $difRojo / $alto;
// Calculamos cuanto G bajar en cada linea
$difVerde = $gFinal - $gInicial;
$difVerde = $difVerde / $alto;
// Calculamos cuanto B bajar en cada linea
$difAzul = $bFinal - $bInicial;
$difAzul = $difAzul / $alto;
// Recorremos la imagen de arriba a abajo
for ($i = 0; $i <= $alto; $i++) {
// Calculamos el color rojo que toca para la linea
$colorRojo = round($rInicial + ($i * $difRojo));
// Y para la letra
($rInicial > $rFinal) ? ($rojoLetra = $rInicial - ($colorRojo - $rFinal)) : ($rojoLetra = $rFinal - ($colorRojo - $rInicial));
// Calculamos el color verde que toca para la linea
$colorVerde = round($gInicial + ($i * $difVerde));
// Y para la letra
($gInicial > $gFinal) ? ($verdeLetra = $gInicial - ($colorVerde - $gFinal)) : ($verdeLetra = $gFinal - ($colorVerde - $gInicial));
// Calculamos el color azul que toca para la linea
$colorAzul = round($bInicial + ($i * $difAzul));
// Y para la letra
($bInicial > $bFinal) ? ($azulLetra = $bInicial - ($colorAzul - $bFinal)) : ($azulLetra = $bFinal - ($colorAzul - $bInicial));
// Preparamos los dos colores
$colorLinea = imagecolorallocate($captcha, $colorRojo, $colorVerde, $colorAzul);
$colorLetra = imagecolorallocate($captcha, $rojoLetra, $verdeLetra, $azulLetra);
// Por cada linea, de izquierda a derecha
for ($x = 0; $x <= $ancho; $x++) {
//Y pintamos segun si es letra o no
(imagecolorat($captcha, $x, $i) != 0) ? (imagesetpixel($captcha, $x, $i, $colorLetra)) : (imagesetpixel($captcha, $x, $i, $colorLinea));
}
}
}
Como podeis ver, esta función es un poco larga. Lo que hace es ir pixel por pixel pintando un degradado desde el primer color hasta el segundo color.
La función necesita 3 parametros, el primero es la imagen, el segundo y el tercero son los colores para hacer el degradado, que ha de tener la estructura R|G|B (por ejemplo, blanco sería 255|255|255)
Únicamente pintará el degradado si encuentra un pixel blanco (fondo), si encuentra uno negro (letra) pintará con el color "opuesto" (no es opuesto como complementario, sino el que está en la misma altura que esa letra pero empezando por abajo).
El resultado es algo parecido a esto:
magiocr.sourceforge.net/delarub.php (aun no me deja poner links jeje)
Como podeis ver, todavia es simple, pero le podéis agregar más cosas, como por ejemplo que los degradados los cree con colores aleatorios (rand()), añadir lineas, cambiar fuentes, etc...
Att, delarub;
magicocr.sourceforge.net