itsolution/module/board/kcaptcha.php
2021-10-26 18:21:20 +09:00

251 lines
8.0 KiB
PHP

<?php
/********************
# KCAPTCHA PROJECT VERSION 1.2.6
# Automatic test to tell computers and humans apart
# Copyright by Kruglov Sergei, 2006, 2007, 2008
# www.captcha.ru, www.kruglov.ru
# System requirements: PHP 4.0.6+ w/ GD
# KCAPTCHA is a free software. You can freely use it for building own site or software.
# If you use this software as a part of own sofware, you must leave copyright notices intact or add KCAPTCHA copyright notices to own.
# As a default configuration, KCAPTCHA has a small credits text at bottom of CAPTCHA image.
# You can remove it, but I would be pleased if you left it. ; )
# See kcaptcha_config.php for customization
********************/
class KCAPTCHA{
// generates keystring and image
function image(){
require( dirname( __FILE__ ).'/kcaptcha_config.php' );
$fonts=array();
$fontsdir_absolute=dirname( __FILE__ ).'/'.$fontsdir;
if ( $handle = opendir( $fontsdir_absolute ) )
{
while ( false !== ( $file = readdir( $handle ) ) )
if ( preg_match( '/\.png$/i', $file ) )
$fonts[]=$fontsdir_absolute.'/'.$file;
closedir( $handle );
}
$alphabet_length = strlen( $alphabet );
do
{
$font_file = $fonts[mt_rand( 0, count( $fonts )-1 )];
$font = imagecreatefrompng( $font_file );
imagealphablending( $font, true );
$fontfile_width = imagesx( $font );
$fontfile_height = imagesy( $font )-1;
$font_metrics = array( );
$symbol = 0;
$reading_symbol = false;
// loading font
for( $i=0; $i<$fontfile_width && $symbol<$alphabet_length; $i++ )
{
$transparent = ( imagecolorat( $font, $i, 0 ) >> 24 ) == 127;
if( !$reading_symbol && !$transparent )
{
$font_metrics[$alphabet{$symbol}] = array( 'start'=>$i );
$reading_symbol = true;
continue;
}
if( $reading_symbol && $transparent )
{
$font_metrics[$alphabet{$symbol}]['end'] = $i;
$reading_symbol = false;
$symbol++;
continue;
}
}
$img = imagecreatetruecolor( $width, $height );
$white = imagecolorallocate( $img, 255, 255, 255 );
$black = imagecolorallocate( $img, 0, 0, 0 );
imagealphablending( $img, true );
imagefilledrectangle( $img, 0, 0, $width-1, $height-1, $white );
// draw text
$x = 1;
for( $i = 0; $i<strlen( $this->keystring ); $i++ )
{
$m=$font_metrics[$this->keystring{$i}];
$y=mt_rand( -$fluctuation_amplitude, $fluctuation_amplitude ) + ( $height-$fontfile_height ) / 2+2;
if( $no_spaces )
{
$shift = 0;
if( $i>0 )
{
$shift = 10000;
for( $sy=7; $sy<$fontfile_height-20; $sy += 1 )
{
for( $sx = $m['start']-1; $sx<$m['end']; $sx += 1 )
{
$rgb = imagecolorat( $font, $sx, $sy );
$opacity = $rgb >> 24;
if( $opacity<127 )
{
$left = $sx-$m['start']+$x;
$py = $sy+$y;
if( $py>$height ) break;
for( $px = min( $left,$width-1 ); $px>$left-12 && $px>=0; $px -= 1 )
{
$color = imagecolorat( $img, $px, $py ) & 0xff;
if( $color+$opacity<190 )
{
if( $shift>$left-$px )
$shift=$left-$px;
break;
}
}
break;
}
}
}
if( $shift===10000 )
$shift = mt_rand( 4,6 );
}
}
else
$shift = 1;
imagecopy( $img, $font, $x-$shift, $y, $m['start'], 1, $m['end']-$m['start'], $fontfile_height );
$x += $m['end']-$m['start']-$shift;
}
}
while( $x>=$width-10 ); // while not fit in canvas
$center = $x/2;
// credits. To remove, see configuration file
$img2 = imagecreatetruecolor( $width, $height+( $show_credits ? 12 : 0 ) );
$foreground = imagecolorallocate( $img2, $foreground_color['0'], $foreground_color['1'], $foreground_color['2'] );
$background = imagecolorallocate( $img2, $background_color['0'], $background_color['1'], $background_color['2'] );
$credits = empty( $credits ) ? $_SERVER['HTTP_HOST'] : $credits;
imagefilledrectangle( $img2, 0, 0, $width-1, $height-1, $background );
imagefilledrectangle( $img2, 0, $height, $width-1, $height+12, $foreground );
imagestring( $img2, 2, $width/2-imagefontwidth( 2 )*strlen( $credits )/2, $height-2, $credits, $background );
// periods
$rand1 = mt_rand( 750000,1200000 )/10000000;
$rand2 = mt_rand( 750000,1200000 )/10000000;
$rand3 = mt_rand( 750000,1200000 )/10000000;
$rand4 = mt_rand( 750000,1200000 )/10000000;
// phases
$rand5 = mt_rand( 0,31415926 )/10000000;
$rand6 = mt_rand( 0,31415926 )/10000000;
$rand7 = mt_rand( 0,31415926 )/10000000;
$rand8 = mt_rand( 0,31415926 )/10000000;
// amplitudes
$rand9 = mt_rand( 330,420 )/110;
$rand10 = mt_rand( 330,450 )/110;
//wave distortion
for( $x = 0; $x<$width; $x++ )
{
for( $y = 0; $y<$height; $y++ )
{
if ( $wave )
{
$sx = $x+( sin( $x*$rand1+$rand5 )+sin( $y*$rand3+$rand6 ) )*$rand9-$width/2+$center+1;
$sy = $y+( sin( $x*$rand2+$rand7 )+sin( $y*$rand4+$rand8 ) )*$rand10;
}
else
{
$sx = $x-$width/2+$center+1;
$sy = $y+( sin( $x*$rand2+$rand7 )+sin( $y*$rand4+$rand8 ) )*1.5;
}
if( $sx<0 || $sy<0 || $sx>=$width-1 || $sy>=$height-1 )
{
continue;
}
else
{
$color = imagecolorat( $img, $sx, $sy ) & 0xFF;
$color_x = imagecolorat( $img, $sx+1, $sy ) & 0xFF;
$color_y = imagecolorat( $img, $sx, $sy+1 ) & 0xFF;
$color_xy = imagecolorat( $img, $sx+1, $sy+1 ) & 0xFF;
}
if( $color==255 && $color_x==255 && $color_y==255 && $color_xy==255 )
{
continue;
}
else if( $color==0 && $color_x==0 && $color_y==0 && $color_xy==0 )
{
$newred = $foreground_color['0'];
$newgreen = $foreground_color['1'];
$newblue = $foreground_color['2'];
}
else
{
$frsx = $sx-floor( $sx );
$frsy = $sy-floor( $sy );
$frsx1 = 1-$frsx;
$frsy1 = 1-$frsy;
$newcolor = ($color*$frsx1*$frsy1+
$color_x*$frsx*$frsy1+
$color_y*$frsx1*$frsy+
$color_xy*$frsx*$frsy
);
if( $newcolor>255 )
$newcolor = 255;
$newcolor = $newcolor/255;
$newcolor0 = 1-$newcolor;
$newred = $newcolor0*$foreground_color['0']+$newcolor*$background_color['0'];
$newgreen = $newcolor0*$foreground_color['1']+$newcolor*$background_color['1'];
$newblue = $newcolor0*$foreground_color['2']+$newcolor*$background_color['2'];
}
imagesetpixel( $img2, $x, $y, imagecolorallocate( $img2, $newred, $newgreen, $newblue ) );
}
}
header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Cache-Control: post-check=0, pre-check=0', FALSE );
header( 'Pragma: no-cache' );
if( function_exists( "imagejpeg" ) )
{
header( "Content-Type: image/jpeg" );
imagejpeg( $img2, null, $jpeg_quality );
}
else if( function_exists( "imagegif" ) )
{
header( "Content-Type: image/gif" );
imagegif( $img2 );
}
else if( function_exists( "imagepng" ) )
{
header( "Content-Type: image/x-png" );
imagepng( $img2 );
}
}
// returns keystring
function getKeyString( )
{
return $this->keystring;
}
function setKeyString( $str )
{
$this->keystring = $str;
}
}
?>