Test Foro de elhacker.net SMF 2.1

Programación => Desarrollo Web => PHP => Mensaje iniciado por: WHK en 8 Enero 2011, 22:34 PM

Título: SuperCaptcha animada by WHK
Publicado por: WHK en 8 Enero 2011, 22:34 PM
hace tiempo hize un sistema de captcha utilizando la clase gifencoder que estuve usando en algunos sistemas mios, pero quiero compartilo xD

demo:
(http://test.drawcoders.net/captcha/?seg=0)

(http://test.drawcoders.net/captcha/?seg=1)

(http://test.drawcoders.net/captcha/?seg=2)

descarga: http://test.drawcoders.net/captcha/captcha.zip

rutas:
C:\xampp\htdocs\captcha>tree /f
Listado de rutas de carpetas
El número de serie del volumen es 00000200 BAEF:7637
C:.
│   index.php

└───includes
       captcha_fuente(bad).ttf
       captcha_fuente(beatnik).ttf
       captcha_fuente(belweb).ttf
       captcha_fuente(BERTRAMN).ttf
       captcha_fuente(butch).ttf
       captcha_fuente(cadellin).ttf
       captcha_fuente(candles).ttf
       GIFEncoder.class.php


captcha.php
Código (php) [Seleccionar]
<?php
$captcha 
= new captcha();

if((int)
$_GET['seg'] == 0){
 
$captcha->mostrar(0);
}elseif((int)
$_GET['seg'] == 2){
 
$captcha->mostrar(2);
}else{ 
/* 1 */
 
$captcha->mostrar(1);
}

class 
captcha{
 var 
$dir_data;

 function 
__construct(){
  
$this->dir_data './includes/';
 }
 
 function 
obtener_hash(){
  return 
$_SESSION['CAPTCHA'];
  
session_destroy();
 }

 function 
establecer_hash(){
  
$hash strtoupper(str_ireplace(
   array(
'o','0','i','l','1','y','s','5','8','7','t','6','b','d','u','q','2','z'),
   array(
'f','r','p','w','x','k','9','a','3','a','m','w','f','3','e','h','c','n'), 
   
substr(sha1(time().rand(0,100)), 04)
  ));
  
$_SESSION['CAPTCHA'] = $hash;
  return 
$hash;
 }

 function 
color_azar($handle){
  return 
imagecolorallocate($handlerand(0,255), rand(0,255), rand(0,255));
 }

 function 
crear_frame($buffer$fuente$seguridad 1){
  
/* Configuraciones */
  
$alto 25;
  
$ancho 160;
  
$lineas 30;
  
  
$handle imagecreate($ancho$alto);
 
  if(
$seguridad <= '1'){ /* Seguridad igual o menor a 1 */
   
$blanco imagecolorallocate($handle255255255);
   
$negro  imagecolorallocate($handle515151);
  }elseif(
$seguridad >= '2'){ /* Seguridad igual o mayor a 2 */
   
$blanco imagecolorallocate($handlerand(0255), rand(0255), rand(0255));
   
$negro  imagecolorallocate($handlerand(0255), rand(0255), rand(0255));
  }
 
  
/* Agrega las lineas */
  
if($seguridad >= '1'){ /* Seguridad igual o mayor a 1 */
   
for($cuenta 1$cuenta <= $lineas$cuenta++){
    
imageline($handlerand(0,$ancho), 0rand(0,$ancho), 25$this->color_azar($handle));
   }
  }
 
  
imagettftext($handle2002222$negro$fuentestrtoupper($buffer));
  
ob_end_clean(); /* Elimina la declaración de inicio de buffers anteriores en el motor */
  
ob_start(); /* Comienza a capturar buffer */
  
imagegif($handle); /* Crea imagen */
  
$retorno ob_get_contents(); /* Vuelca el contenido a la variable */
  
imagedestroy($handle); /* Libera memoria */
  
ob_end_clean(); /* Destruye el buffer */
  
return $retorno/* Retorna el buffer de la imagen */
 
}

 function 
mostrar($seguridad 1){
  
/* Seguridad va del 0 al 2 */
  
$string $this->establecer_hash();
  include(
$this->dir_data .'GIFEncoder.class.php');
  
$cantidad_frames 10;
  
$fuente glob($this->dir_data .'/captcha_fuente(*).ttf');
  
$fuente $fuente[(int)rand(0count($fuente) - 1)];
 
  for(
$cuenta 0$cuenta <= $cantidad_frames$cuenta++){
   
$buffer $this->crear_frame($string$fuente$seguridad);
   
$rutas_frames[$cuenta] = sys_get_temp_dir().'/'.md5(microtime().rand(10500)).'.gif';
   
file_put_contents($rutas_frames[$cuenta], $buffer);
   unset(
$buffer);
  }

  
$gif = new GIFEncoder($rutas_framesfalse02000'url');
 
  foreach(
$rutas_frames as $eliminar){
   @
unlink($eliminar);
  }
 
  
header('Content-type: image/gif');
  echo 
$gif->GetAnimation();
  exit;
 }

}

?>


GIFEncoder.class.php
Código (php) [Seleccionar]
<?php
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFEncoder Version 2.0 by László Zsidi, http://gifs.hu
::
:: This class is a rewritten 'GifMerge.class.php' version.
::
::  Modification:
::   - Simplified and easy code,
::   - Ultra fast encoding,
::   - Built-in errors,
::   - Stable working
::
::
:: Updated at 2007. 02. 13. '00.05.AM'
::
::
::
::  Try on-line GIFBuilder Form demo based on GIFEncoder.
::
::  http://gifs.hu/phpclasses/demos/GifBuilder/
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*/

Class GIFEncoder {
var $GIF "GIF89a"; /* GIF header 6 bytes */
var $VER "GIFEncoder V2.05"; /* Encoder version */

var $BUF = Array ( );
var $LOP =  0;
var $DIS =  2;
var $COL = -1;
var $IMG = -1;

var $ERR = Array (
ERR00=>"Does not supported function for only one image!",
ERR01=>"Source is not a GIF image!",
ERR02=>"Unintelligible flag ",
ERR03=>"Does not make animation from animated GIF source",
);

/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFEncoder...
::
*/
function GIFEncoder (
$GIF_src$GIF_dly$GIF_lop$GIF_dis,
$GIF_red$GIF_grn$GIF_blu$GIF_mod
) {
if ( ! is_array $GIF_src ) && ! is_array $GIF_tim ) ) {
printf "%s: %s"$this->VER$this->ERR 'ERR00' ] );
exit );
}
$this->LOP = ( $GIF_lop > -) ? $GIF_lop 0;
$this->DIS = ( $GIF_dis > -) ? ( ( $GIF_dis ) ? $GIF_dis ) : 2;
$this->COL = ( $GIF_red > -&& $GIF_grn > -&& $GIF_blu > -) ?
$GIF_red | ( $GIF_grn << ) | ( $GIF_blu << 16 ) ) : -1;

for ( $i 0$i count $GIF_src ); $i++ ) {
if ( strToLower $GIF_mod ) == "url" ) {
$this->BUF [ ] = fread fopen $GIF_src $i ], "rb" ), filesize $GIF_src $i ] ) );
}
else if ( strToLower $GIF_mod ) == "bin" ) {
$this->BUF [ ] = $GIF_src $i ];
}
else {
printf "%s: %s ( %s )!"$this->VER$this->ERR 'ERR02' ], $GIF_mod );
exit );
}
if ( substr $this->BUF $i ], 0) != "GIF87a" && substr $this->BUF $i ], 0) != "GIF89a" ) {
printf "%s: %d %s"$this->VER$i$this->ERR 'ERR01' ] );
exit );
}
for ( $j = ( 13 * ( << ( ord $this->BUF $i ] { 10 } ) & 0x07 ) ) ), $k TRUE$k$j++ ) {
switch ( $this->BUF $i ] { $j } ) {
case "!":
if ( ( substr $this->BUF $i ], ( $j ), ) ) == "NETSCAPE" ) {
printf "%s: %s ( %s source )!"$this->VER$this->ERR 'ERR03' ], ( $i ) );
exit );
}
break;
case ";":
$k FALSE;
break;
}
}
}
GIFEncoder::GIFAddHeader ( );
for ( $i 0$i count $this->BUF ); $i++ ) {
GIFEncoder::GIFAddFrames $i$GIF_dly $i ] );
}
GIFEncoder::GIFAddFooter ( );
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFAddHeader...
::
*/
function GIFAddHeader ( ) {
$cmap 0;

if ( ord $this->BUF ] { 10 } ) & 0x80 ) {
$cmap * ( << ( ord $this->BUF ] { 10 } ) & 0x07 ) );

$this->GIF .= substr $this->BUF ], 67 );
$this->GIF .= substr $this->BUF ], 13$cmap );
$this->GIF .= "!\377\13NETSCAPE2.0\3\1" GIFEncoder::GIFWord $this->LOP ) . "\0";
}
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFAddFrames...
::
*/
function GIFAddFrames $i$d ) {

$Locals_str 13 * ( << ( ord $this->BUF $i ] { 10 } ) & 0x07 ) );

$Locals_end strlen $this->BUF $i ] ) - $Locals_str 1;
$Locals_tmp substr $this->BUF $i ], $Locals_str$Locals_end );

$Global_len << ( ord $this->BUF 0  ] { 10 } ) & 0x07 );
$Locals_len << ( ord $this->BUF $i ] { 10 } ) & 0x07 );

$Global_rgb substr $this->BUF 0  ], 13,
* ( << ( ord $this->BUF 0  ] { 10 } ) & 0x07 ) ) );
$Locals_rgb substr $this->BUF $i ], 13,
* ( << ( ord $this->BUF $i ] { 10 } ) & 0x07 ) ) );

$Locals_ext "!\xF9\x04" chr ( ( $this->DIS << ) + ) .
chr ( ( $d >> ) & 0xFF ) . chr ( ( $d >> ) & 0xFF ) . "\x0\x0";

if ( $this->COL > -&& ord $this->BUF $i ] { 10 } ) & 0x80 ) {
for ( $j 0$j < ( << ( ord $this->BUF $i ] { 10 } ) & 0x07 ) ); $j++ ) {
if (
ord $Locals_rgb $j } ) == ( ( $this->COL >> 16 ) & 0xFF ) &&
ord $Locals_rgb $j } ) == ( ( $this->COL >>  ) & 0xFF ) &&
ord $Locals_rgb $j } ) == ( ( $this->COL >>  ) & 0xFF )
) {
$Locals_ext "!\xF9\x04" chr ( ( $this->DIS << ) + ) .
chr ( ( $d >> ) & 0xFF ) . chr ( ( $d >> ) & 0xFF ) . chr $j ) . "\x0";
break;
}
}
}
switch ( $Locals_tmp } ) {
case "!":
$Locals_img substr $Locals_tmp810 );
$Locals_tmp substr $Locals_tmp18strlen $Locals_tmp ) - 18 );
break;
case ",":
$Locals_img substr $Locals_tmp010 );
$Locals_tmp substr $Locals_tmp10strlen $Locals_tmp ) - 10 );
break;
}
if ( ord $this->BUF $i ] { 10 } ) & 0x80 && $this->IMG > -) {
if ( $Global_len == $Locals_len ) {
if ( GIFEncoder::GIFBlockCompare $Global_rgb$Locals_rgb$Global_len ) ) {
$this->GIF .= ( $Locals_ext $Locals_img $Locals_tmp );
}
else {
$byte  ord $Locals_img } );
$byte |= 0x80;
$byte &= 0xF8;
$byte |= ( ord $this->BUF ] { 10 } ) & 0x07 );
$Locals_img } = chr $byte );
$this->GIF .= ( $Locals_ext $Locals_img $Locals_rgb $Locals_tmp );
}
}
else {
$byte  ord $Locals_img } );
$byte |= 0x80;
$byte &= 0xF8;
$byte |= ( ord $this->BUF $i ] { 10 } ) & 0x07 );
$Locals_img } = chr $byte );
$this->GIF .= ( $Locals_ext $Locals_img $Locals_rgb $Locals_tmp );
}
}
else {
$this->GIF .= ( $Locals_ext $Locals_img $Locals_tmp );
}
$this->IMG  1;
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFAddFooter...
::
*/
function GIFAddFooter ( ) {
$this->GIF .= ";";
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFBlockCompare...
::
*/
function GIFBlockCompare $GlobalBlock$LocalBlock$Len ) {

for ( $i 0$i $Len$i++ ) {
if (
$GlobalBlock $i } != $LocalBlock $i } ||
$GlobalBlock $i } != $LocalBlock $i } ||
$GlobalBlock $i } != $LocalBlock $i }
) {
return ( );
}
}

return ( );
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GIFWord...
::
*/
function GIFWord $int ) {

return ( chr $int 0xFF ) . chr ( ( $int >> ) & 0xFF ) );
}
/*
:::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: GetAnimation...
::
*/
function GetAnimation ( ) {
return ( $this->GIF );
}
}
?>
Título: Re: SuperCaptcha animada by WHK
Publicado por: raul338 en 9 Enero 2011, 00:13 AM
Wow... muy lindo y muy bueno! :)

Cita de: WHK en  8 Enero 2011, 22:34 PM
Código (php) [Seleccionar]

function obtener_hash(){
  return $_SESSION['CAPTCHA'];
  session_destroy();
}

Lo que no entiendo es porque usas session_destroy que rompe todo, y porque no unset que ahi solo liberarias el captcha? Lo digo porque si hay una pagina con uso intensivo de $_SESSION agregar este script lo romperia :xD
Título: Re: SuperCaptcha animada by WHK
Publicado por: WHK en 9 Enero 2011, 00:31 AM
Cita de: raul338 en  9 Enero 2011, 00:13 AM
Wow... muy lindo y muy bueno! :)
Lo que no entiendo es porque usas session_destroy que rompe todo, y porque no unset que ahi solo liberarias el captcha? Lo digo porque si hay una pagina con uso intensivo de $_SESSION agregar este script lo romperia :xD

haces el formulario con la imágen y llamas solamente a la función mostrar() donde inicia sesión, esta función de php te crea un archivo temporal con los datos serializados.

al enviar el formulario se obtiene el valor de la imagen anterior con obtener_hash() y esto elimina el archivo temporal. se compara con $_POST del formulario y procesas lo que quieras, redireciconas o cargas algo o muestras algo.

si el texto falla mas abajo buelve a cargar la imágen y eso hará que buelva a iniciar sesion con un nuevo hash :P

si no destruyera la sesión al momento de procesar la captcha entonces quedarias con tu directorio temporal con gigas de archivos basura sin eliminar como le pasó a un amigo con un plugin de vbulletín. si no destruyes sesiones te quedas con los archivos temporales hechos.
Título: Re: SuperCaptcha animada by WHK
Publicado por: raul338 en 9 Enero 2011, 02:58 AM
Pero que pasa si llevaba otros datos antes de entrar al script que llama al captcha y los necesite despues. Tengo entendido que sesion_destroy los borra completamente :|
Título: Re: SuperCaptcha animada by WHK
Publicado por: WHK en 9 Enero 2011, 17:21 PM
eso ya sería opcional porque si no lo hubiera puesto y no usas sesiones despues hubieras dicho que no destruyo la sesion y que soy hereje por destruir servidores xD
Título: Re: SuperCaptcha animada by WHK
Publicado por: R@mi en 10 Enero 2011, 01:58 AM
 :rolleyes: genial

;-) ;-) ;-)
Título: Re: SuperCaptcha animada by WHK
Publicado por: Graphixx en 5 Marzo 2012, 23:16 PM
Alguien podria resubir el codigo, intente compilarlo con los archivos posteados y me retorna:

Warning: imagettftext() [function.imagettftext]: Could not find/open font in D:\_SERVIDOR2\www\chicamall\captchawhk\captcha.php on line 64

Warning: Cannot modify header information - headers already sent by (output started at D:\_SERVIDOR2\www\chicamall\captchawhk\captcha.php:64) in D:\_SERVIDOR2\www\chicamall\captchawhk\captcha.php on line 95
GIF89a €ÿÿÿ333!ÿ NETSCAPE2.0!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l!ù, C,,©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·\l;
Título: Re: SuperCaptcha animada by WHK
Publicado por: WHK en 6 Marzo 2012, 13:23 PM
Lo que te falta son los archivos ttf para crear los textos, puedes agregarle cualquier fuente de texto, solo debe tener el nombre  captcha_fuente(*).ttf

Mas tarde subo las fuentes.
De todas formas esa captcha es parte de mi framework, si quieres te puedo dar el framework completo para que le des un vistazo y te doy unos ejemplos de como usar la captcha. Solo debes solicitarlo acá:
http://whk.drawcoders.com/foro/index.php/board,50.0.html

Y me posteas lo que necesitas hacer y te escribo un par de ejemplos ahi mismo.
Título: Re: SuperCaptcha animada by WHK
Publicado por: Graphixx en 7 Marzo 2012, 02:15 AM
Gracias compa ya me registre por aya por drawcoders, quedo atento al Frame pa observar el code del captcha.