@ -1,386 +1,386 @@
< ? php
/**
* Script for generation of CAPTCHAs
*
* @ author Jose Rodriguez < jose . rodriguez @ exec . cl >
* @ license GPLv3
* @ link http :// code . google . com / p / cool - php - captcha
* @ version 0.3
*
*/
session_start ();
putenv ( 'GDFONTPATH=' . realpath ( './fonts/' ));
$captcha = new SimpleCaptcha ();
$captcha -> CreateImage ();
/**
* SimpleCaptcha class
*
*/
class SimpleCaptcha {
/** Width of the image */
public $width = 175 ;
/** Height of the image */
public $height = 55 ;
/** Dictionary word file (empty for random text) */
public $wordsFile = '' ;
/**
* Path for resource files ( fonts , words , etc . )
*
* " resources " by default . For security reasons , is better move this
* directory to another location out i se the web server
*
*/
public $resourcesPath = './fonts' ;
/** Min word length (for non-dictionary random text generation) */
public $minWordLength = 4 ;
/**
* Max word length ( for non - dictionary random text generation )
*
* Used for dictionary words indicating the word - length
* for font - size modification purposes
*/
public $maxWordLength = 6 ;
/** Sessionname to store the original text */
public $session_var = 'tinyibcaptcha' ;
/** Background color in RGB-array */
public $backgroundColor = array ( 254 , 254 , 254 );
/** Foreground colors in RGB-array */
public $colors = array (
array ( 27 , 78 , 181 ), // blue
array ( 22 , 163 , 35 ), // green
array ( 214 , 36 , 7 ), // red
);
/** Shadow color in RGB-array or null */
public $shadowColor = array ( 0 , 0 , 0 );
/** Horizontal line through the text */
public $lineWidth = 3 ;
/**
* Font configuration
*
* - font : TTF file
* - spacing : relative pixel space between character
* - minSize : min font size
* - maxSize : max font size
*/
public $fonts = array (
'Roboto-Regular' => array ( 'spacing' => 0 , 'minSize' => 27 , 'maxSize' => 27 , 'font' => 'roboto_regular.ttf' ),
'Roboto-Bold' => array ( 'spacing' => 0 , 'minSize' => 27 , 'maxSize' => 27 , 'font' => 'roboto_bold.ttf' )
);
/** Wave configura c ion in X and Y axes */
public $Yperiod = 12 ;
public $Yamplitude = 14 ;
public $Xperiod = 11 ;
public $Xamplitude = 5 ;
/** letter rotation clockwise */
public $maxRotation = 8 ;
/**
* Internal image size factor ( for better image quality )
* 1 : low , 2 : medium , 3 : high
*/
public $scale = 3 ;
/**
* Blur effect for better image quality ( but slower image processing ) .
* Better image results with scale = 3
*/
public $blur = true ;
/** Debug? */
public $debug = false ;
/** Image format: jpeg or png */
public $imageFormat = 'png' ;
/** GD image */
public $im ;
public function __construct ( $config = array ()) {
}
public function CreateImage () {
$ini = microtime ( true );
/** Initialization */
$this -> ImageAllocate ();
/** Text insertion */
$text = $this -> GetCaptchaText ();
$fontcfg = $this -> fonts [ array_rand ( $this -> fonts )];
$this -> WriteText ( $text , $fontcfg );
$_SESSION [ $this -> session_var ] = $text ;
/** Transformations */
if ( ! empty ( $this -> lineWidth )) {
$this -> WriteLine ();
}
$this -> WaveImage ();
if ( $this -> blur && function_exists ( 'imagefilter' )) {
imagefilter ( $this -> im , IMG_FILTER_GAUSSIAN_BLUR );
}
$this -> ReduceImage ();
if ( $this -> debug ) {
imagestring ( $this -> im , 1 , 1 , $this -> height - 8 ,
" $text { $fontcfg [ 'font' ] } " . round (( microtime ( true ) - $ini ) * 1000 ) . " ms " ,
$this -> GdFgColor
);
}
/** Output */
$this -> WriteImage ();
$this -> Cleanup ();
}
/**
* Creates the image resources
*/
protected function ImageAllocate () {
// Cleanup
if ( ! empty ( $this -> im )) {
imagedestroy ( $this -> im );
}
$this -> im = imagecreatetruecolor ( $this -> width * $this -> scale , $this -> height * $this -> scale );
// Background color
$this -> GdBgColor = imagecolorallocate ( $this -> im ,
$this -> backgroundColor [ 0 ],
$this -> backgroundColor [ 1 ],
$this -> backgroundColor [ 2 ]
);
imagefilledrectangle ( $this -> im , 0 , 0 , $this -> width * $this -> scale , $this -> height * $this -> scale , $this -> GdBgColor );
// Foreground color
$color = $this -> colors [ mt_rand ( 0 , sizeof ( $this -> colors ) - 1 )];
$this -> GdFgColor = imagecolorallocate ( $this -> im , $color [ 0 ], $color [ 1 ], $color [ 2 ]);
// Shadow color
if ( ! empty ( $this -> shadowColor ) && is_array ( $this -> shadowColor ) && sizeof ( $this -> shadowColor ) >= 3 ) {
$this -> GdShadowColor = imagecolorallocate ( $this -> im ,
$this -> shadowColor [ 0 ],
$this -> shadowColor [ 1 ],
$this -> shadowColor [ 2 ]
);
}
}
/**
* Text generation
*
* @ return string Text
*/
protected function GetCaptchaText () {
$text = $this -> GetDictionaryCaptchaText ();
if ( ! $text ) {
$text = $this -> GetRandomCaptchaText ();
}
return $text ;
}
/**
* Random text generation
*
* @ return string Text
*/
protected function GetRandomCaptchaText ( $length = null ) {
if ( empty ( $length )) {
$length = rand ( $this -> minWordLength , $this -> maxWordLength );
}
$words = " abcdefghijlmnopqrstvwyz " ;
$vocals = " aeiou " ;
$text = " " ;
$vocal = rand ( 0 , 1 );
for ( $i = 0 ; $i < $length ; $i ++ ) {
if ( $vocal ) {
$text .= substr ( $vocals , mt_rand ( 0 , 4 ), 1 );
} else {
$text .= substr ( $words , mt_rand ( 0 , 22 ), 1 );
}
$vocal = ! $vocal ;
}
return $text ;
}
/**
* Random dictionary word generation
*
* @ param boolean $extended Add extended " fake " words
* @ return string Word
*/
function GetDictionaryCaptchaText ( $extended = false ) {
if ( empty ( $this -> wordsFile )) {
return false ;
}
// Full path of words file
if ( substr ( $this -> wordsFile , 0 , 1 ) == '/' ) {
$wordsfile = $this -> wordsFile ;
} else {
$wordsfile = $this -> resourcesPath . '/' . $this -> wordsFile ;
}
if ( ! file_exists ( $wordsfile )) {
return false ;
}
$fp = fopen ( $wordsfile , " r " );
$length = strlen ( fgets ( $fp ));
if ( ! $length ) {
return false ;
}
$line = rand ( 1 , ( filesize ( $wordsfile ) / $length ) - 2 );
if ( fseek ( $fp , $length * $line ) == - 1 ) {
return false ;
}
$text = trim ( fgets ( $fp ));
fclose ( $fp );
/** Change ra m dom volcals */
if ( $extended ) {
$text = preg_split ( '//' , $text , - 1 , PREG_SPLIT_NO_EMPTY );
$vocals = array ( 'a' , 'e' , 'i' , 'o' , 'u' );
foreach ( $text as $i => $char ) {
if ( mt_rand ( 0 , 1 ) && in_array ( $char , $vocals )) {
$text [ $i ] = $vocals [ mt_rand ( 0 , 4 )];
}
}
$text = implode ( '' , $text );
}
return $text ;
}
/**
* Horizontal line insertion
*/
protected function WriteLine () {
$x1 = $this -> width * $this -> scale * . 15 ;
$x2 = $this -> textFinalX ;
$y1 = rand ( $this -> height * $this -> scale * . 40 , $this -> height * $this -> scale * . 65 );
$y2 = rand ( $this -> height * $this -> scale * . 40 , $this -> height * $this -> scale * . 65 );
$width = $this -> lineWidth / 2 * $this -> scale ;
for ( $i = $width * - 1 ; $i <= $width ; $i ++ ) {
imageline ( $this -> im , $x1 , $y1 + $i , $x2 , $y2 + $i , $this -> GdFgColor );
}
}
/**
* Text insertion
*/
protected function WriteText ( $text , $fontcfg = array ()) {
if ( empty ( $fontcfg )) {
// Select the font configuration
$fontcfg = $this -> fonts [ array_rand ( $this -> fonts )];
}
$fontfile = $fontcfg [ 'font' ];
/** Increase font-size for shortest words: 9% for each glyph missing */
$lettersMissing = $this -> maxWordLength - strlen ( $text );
$fontSizefactor = 1 + ( $lettersMissing * 0.09 );
// Text generation (char by char)
$x = 20 * $this -> scale ;
$y = round (( $this -> height * 27 / 40 ) * $this -> scale );
$length = strlen ( $text );
for ( $i = 0 ; $i < $length ; $i ++ ) {
$degree = rand ( $this -> maxRotation * - 1 , $this -> maxRotation );
$fontsize = rand ( $fontcfg [ 'minSize' ], $fontcfg [ 'maxSize' ]) * $this -> scale * $fontSizefactor ;
$letter = substr ( $text , $i , 1 );
if ( $this -> shadowColor ) {
$coords = imagettftext ( $this -> im , $fontsize , $degree ,
$x + $this -> scale , $y + $this -> scale ,
$this -> GdShadowColor , $fontfile , $letter );
}
$coords = imagettftext ( $this -> im , $fontsize , $degree ,
$x , $y ,
$this -> GdFgColor , $fontfile , $letter );
$x += ( $coords [ 2 ] - $x ) + ( $fontcfg [ 'spacing' ] * $this -> scale );
}
$this -> textFinalX = $x ;
}
/**
* Wave filter
*/
protected function WaveImage () {
// X-axis wave generation
$xp = $this -> scale * $this -> Xperiod * rand ( 1 , 3 );
$k = rand ( 0 , 100 );
for ( $i = 0 ; $i < ( $this -> width * $this -> scale ); $i ++ ) {
imagecopy ( $this -> im , $this -> im ,
$i - 1 , sin ( $k + $i / $xp ) * ( $this -> scale * $this -> Xamplitude ),
$i , 0 , 1 , $this -> height * $this -> scale );
}
// Y-axis wave generation
$k = rand ( 0 , 100 );
$yp = $this -> scale * $this -> Yperiod * rand ( 1 , 2 );
for ( $i = 0 ; $i < ( $this -> height * $this -> scale ); $i ++ ) {
imagecopy ( $this -> im , $this -> im ,
sin ( $k + $i / $yp ) * ( $this -> scale * $this -> Yamplitude ), $i - 1 ,
0 , $i , $this -> width * $this -> scale , 1 );
}
}
/**
* Reduce the image to the final size
*/
protected function ReduceImage () {
// Reduzco el tama<6D> o de la imagen
$imResampled = imagecreatetruecolor ( $this -> width , $this -> height );
imagecopyresampled ( $imResampled , $this -> im ,
0 , 0 , 0 , 0 ,
$this -> width , $this -> height ,
$this -> width * $this -> scale , $this -> height * $this -> scale
);
imagedestroy ( $this -> im );
$this -> im = $imResampled ;
}
/**
* File generation
*/
protected function WriteImage () {
if ( $this -> imageFormat == 'png' && function_exists ( 'imagepng' )) {
imagealphablending ( $this -> im , true );
imagesavealpha ( $this -> im , false );
imagecolortransparent ( $this -> im , $this -> GdBgColor );
header ( " Content-type: image/png " );
imagepng ( $this -> im );
} else {
header ( " Content-type: image/jpeg " );
imagejpeg ( $this -> im , null , 80 );
}
}
/**
* Cleanup
*/
protected function Cleanup () {
imagedestroy ( $this -> im );
}
}
< ? php
/**
* Script for generation of CAPTCHAs
*
* @ author Jose Rodriguez < jose . rodriguez @ exec . cl >
* @ license GPLv3
* @ link http :// code . google . com / p / cool - php - captcha
* @ version 0.3
*
*/
session_start ();
putenv ( 'GDFONTPATH=' . realpath ( './fonts/' ));
$captcha = new SimpleCaptcha ();
$captcha -> CreateImage ();
/**
* SimpleCaptcha class
*
*/
class SimpleCaptcha {
/** Width of the image */
public $width = 175 ;
/** Height of the image */
public $height = 55 ;
/** Dictionary word file (empty for random text) */
public $wordsFile = '' ;
/**
* Path for resource files ( fonts , words , etc . )
*
* " resources " by default . For security reasons , is better move this
* directory to another location out sid e the web server
*
*/
public $resourcesPath = './fonts' ;
/** Min word length (for non-dictionary random text generation) */
public $minWordLength = 4 ;
/**
* Max word length ( for non - dictionary random text generation )
*
* Used for dictionary words indicating the word - length
* for font - size modification purposes
*/
public $maxWordLength = 6 ;
/** Sessionname to store the original text */
public $session_var = 'tinyibcaptcha' ;
/** Background color in RGB-array */
public $backgroundColor = array ( 254 , 254 , 254 );
/** Foreground colors in RGB-array */
public $colors = array (
array ( 27 , 78 , 181 ), // blue
array ( 22 , 163 , 35 ), // green
array ( 214 , 36 , 7 ), // red
);
/** Shadow color in RGB-array or null */
public $shadowColor = array ( 0 , 0 , 0 );
/** Horizontal line through the text */
public $lineWidth = 3 ;
/**
* Font configuration
*
* - font : TTF file
* - spacing : relative pixel space between character
* - minSize : min font size
* - maxSize : max font size
*/
public $fonts = array (
'Roboto-Regular' => array ( 'spacing' => 0 , 'minSize' => 27 , 'maxSize' => 27 , 'font' => 'roboto_regular.ttf' ),
'Roboto-Bold' => array ( 'spacing' => 0 , 'minSize' => 27 , 'maxSize' => 27 , 'font' => 'roboto_bold.ttf' )
);
/** Wave configura t ion in X and Y axes */
public $Yperiod = 12 ;
public $Yamplitude = 14 ;
public $Xperiod = 11 ;
public $Xamplitude = 5 ;
/** letter rotation clockwise */
public $maxRotation = 8 ;
/**
* Internal image size factor ( for better image quality )
* 1 : low , 2 : medium , 3 : high
*/
public $scale = 3 ;
/**
* Blur effect for better image quality ( but slower image processing ) .
* Better image results with scale = 3
*/
public $blur = true ;
/** Debug? */
public $debug = false ;
/** Image format: jpeg or png */
public $imageFormat = 'png' ;
/** GD image */
public $im ;
public function __construct ( $config = array ()) {
}
public function CreateImage () {
$ini = microtime ( true );
/** Initialization */
$this -> ImageAllocate ();
/** Text insertion */
$text = $this -> GetCaptchaText ();
$fontcfg = $this -> fonts [ array_rand ( $this -> fonts )];
$this -> WriteText ( $text , $fontcfg );
$_SESSION [ $this -> session_var ] = $text ;
/** Transformations */
if ( ! empty ( $this -> lineWidth )) {
$this -> WriteLine ();
}
$this -> WaveImage ();
if ( $this -> blur && function_exists ( 'imagefilter' )) {
imagefilter ( $this -> im , IMG_FILTER_GAUSSIAN_BLUR );
}
$this -> ReduceImage ();
if ( $this -> debug ) {
imagestring ( $this -> im , 1 , 1 , $this -> height - 8 ,
" $text { $fontcfg [ 'font' ] } " . round (( microtime ( true ) - $ini ) * 1000 ) . " ms " ,
$this -> GdFgColor
);
}
/** Output */
$this -> WriteImage ();
$this -> Cleanup ();
}
/**
* Creates the image resources
*/
protected function ImageAllocate () {
// Cleanup
if ( ! empty ( $this -> im )) {
imagedestroy ( $this -> im );
}
$this -> im = imagecreatetruecolor ( $this -> width * $this -> scale , $this -> height * $this -> scale );
// Background color
$this -> GdBgColor = imagecolorallocate ( $this -> im ,
$this -> backgroundColor [ 0 ],
$this -> backgroundColor [ 1 ],
$this -> backgroundColor [ 2 ]
);
imagefilledrectangle ( $this -> im , 0 , 0 , $this -> width * $this -> scale , $this -> height * $this -> scale , $this -> GdBgColor );
// Foreground color
$color = $this -> colors [ mt_rand ( 0 , sizeof ( $this -> colors ) - 1 )];
$this -> GdFgColor = imagecolorallocate ( $this -> im , $color [ 0 ], $color [ 1 ], $color [ 2 ]);
// Shadow color
if ( ! empty ( $this -> shadowColor ) && is_array ( $this -> shadowColor ) && sizeof ( $this -> shadowColor ) >= 3 ) {
$this -> GdShadowColor = imagecolorallocate ( $this -> im ,
$this -> shadowColor [ 0 ],
$this -> shadowColor [ 1 ],
$this -> shadowColor [ 2 ]
);
}
}
/**
* Text generation
*
* @ return string Text
*/
protected function GetCaptchaText () {
$text = $this -> GetDictionaryCaptchaText ();
if ( ! $text ) {
$text = $this -> GetRandomCaptchaText ();
}
return $text ;
}
/**
* Random text generation
*
* @ return string Text
*/
protected function GetRandomCaptchaText ( $length = null ) {
if ( empty ( $length )) {
$length = rand ( $this -> minWordLength , $this -> maxWordLength );
}
$words = " abcdefghijlmnopqrstvwyz " ;
$vocals = " aeiou " ;
$text = " " ;
$vocal = rand ( 0 , 1 );
for ( $i = 0 ; $i < $length ; $i ++ ) {
if ( $vocal ) {
$text .= substr ( $vocals , mt_rand ( 0 , 4 ), 1 );
} else {
$text .= substr ( $words , mt_rand ( 0 , 22 ), 1 );
}
$vocal = ! $vocal ;
}
return $text ;
}
/**
* Random dictionary word generation
*
* @ param boolean $extended Add extended " fake " words
* @ return string Word
*/
function GetDictionaryCaptchaText ( $extended = false ) {
if ( empty ( $this -> wordsFile )) {
return false ;
}
// Full path of words file
if ( substr ( $this -> wordsFile , 0 , 1 ) == '/' ) {
$wordsfile = $this -> wordsFile ;
} else {
$wordsfile = $this -> resourcesPath . '/' . $this -> wordsFile ;
}
if ( ! file_exists ( $wordsfile )) {
return false ;
}
$fp = fopen ( $wordsfile , " r " );
$length = strlen ( fgets ( $fp ));
if ( ! $length ) {
return false ;
}
$line = rand ( 1 , ( filesize ( $wordsfile ) / $length ) - 2 );
if ( fseek ( $fp , $length * $line ) == - 1 ) {
return false ;
}
$text = trim ( fgets ( $fp ));
fclose ( $fp );
/** Change ra n dom volcals */
if ( $extended ) {
$text = preg_split ( '//' , $text , - 1 , PREG_SPLIT_NO_EMPTY );
$vocals = array ( 'a' , 'e' , 'i' , 'o' , 'u' );
foreach ( $text as $i => $char ) {
if ( mt_rand ( 0 , 1 ) && in_array ( $char , $vocals )) {
$text [ $i ] = $vocals [ mt_rand ( 0 , 4 )];
}
}
$text = implode ( '' , $text );
}
return $text ;
}
/**
* Horizontal line insertion
*/
protected function WriteLine () {
$x1 = $this -> width * $this -> scale * . 15 ;
$x2 = $this -> textFinalX ;
$y1 = rand ( $this -> height * $this -> scale * . 40 , $this -> height * $this -> scale * . 65 );
$y2 = rand ( $this -> height * $this -> scale * . 40 , $this -> height * $this -> scale * . 65 );
$width = $this -> lineWidth / 2 * $this -> scale ;
for ( $i = $width * - 1 ; $i <= $width ; $i ++ ) {
imageline ( $this -> im , $x1 , $y1 + $i , $x2 , $y2 + $i , $this -> GdFgColor );
}
}
/**
* Text insertion
*/
protected function WriteText ( $text , $fontcfg = array ()) {
if ( empty ( $fontcfg )) {
// Select the font configuration
$fontcfg = $this -> fonts [ array_rand ( $this -> fonts )];
}
$fontfile = $fontcfg [ 'font' ];
/** Increase font-size for shortest words: 9% for each glyph missing */
$lettersMissing = $this -> maxWordLength - strlen ( $text );
$fontSizefactor = 1 + ( $lettersMissing * 0.09 );
// Text generation (char by char)
$x = 20 * $this -> scale ;
$y = round (( $this -> height * 27 / 40 ) * $this -> scale );
$length = strlen ( $text );
for ( $i = 0 ; $i < $length ; $i ++ ) {
$degree = rand ( $this -> maxRotation * - 1 , $this -> maxRotation );
$fontsize = rand ( $fontcfg [ 'minSize' ], $fontcfg [ 'maxSize' ]) * $this -> scale * $fontSizefactor ;
$letter = substr ( $text , $i , 1 );
if ( $this -> shadowColor ) {
$coords = imagettftext ( $this -> im , $fontsize , $degree ,
$x + $this -> scale , $y + $this -> scale ,
$this -> GdShadowColor , $fontfile , $letter );
}
$coords = imagettftext ( $this -> im , $fontsize , $degree ,
$x , $y ,
$this -> GdFgColor , $fontfile , $letter );
$x += ( $coords [ 2 ] - $x ) + ( $fontcfg [ 'spacing' ] * $this -> scale );
}
$this -> textFinalX = $x ;
}
/**
* Wave filter
*/
protected function WaveImage () {
// X-axis wave generation
$xp = $this -> scale * $this -> Xperiod * rand ( 1 , 3 );
$k = rand ( 0 , 100 );
for ( $i = 0 ; $i < ( $this -> width * $this -> scale ); $i ++ ) {
imagecopy ( $this -> im , $this -> im ,
$i - 1 , sin ( $k + $i / $xp ) * ( $this -> scale * $this -> Xamplitude ),
$i , 0 , 1 , $this -> height * $this -> scale );
}
// Y-axis wave generation
$k = rand ( 0 , 100 );
$yp = $this -> scale * $this -> Yperiod * rand ( 1 , 2 );
for ( $i = 0 ; $i < ( $this -> height * $this -> scale ); $i ++ ) {
imagecopy ( $this -> im , $this -> im ,
sin ( $k + $i / $yp ) * ( $this -> scale * $this -> Yamplitude ), $i - 1 ,
0 , $i , $this -> width * $this -> scale , 1 );
}
}
/**
* Reduce the image to the final size
*/
protected function ReduceImage () {
// Reduzco el tama<6D> o de la imagen
$imResampled = imagecreatetruecolor ( $this -> width , $this -> height );
imagecopyresampled ( $imResampled , $this -> im ,
0 , 0 , 0 , 0 ,
$this -> width , $this -> height ,
$this -> width * $this -> scale , $this -> height * $this -> scale
);
imagedestroy ( $this -> im );
$this -> im = $imResampled ;
}
/**
* File generation
*/
protected function WriteImage () {
if ( $this -> imageFormat == 'png' && function_exists ( 'imagepng' )) {
imagealphablending ( $this -> im , true );
imagesavealpha ( $this -> im , false );
imagecolortransparent ( $this -> im , $this -> GdBgColor );
header ( " Content-type: image/png " );
imagepng ( $this -> im );
} else {
header ( " Content-type: image/jpeg " );
imagejpeg ( $this -> im , null , 80 );
}
}
/**
* Cleanup
*/
protected function Cleanup () {
imagedestroy ( $this -> im );
}
}