';
}else{
msg('Failed to load figlet.flf font file. CAPTCHA broken',-1);
}
break;
}
$out .= ' ';
// add honeypot field
$out .= '';
$out .= '
';
return $out;
}
/**
* Checks if the the CAPTCHA was solved correctly
*
* @param bool $msg when true, an error will be signalled through the msg() method
* @return bool true when the answer was correct, otherwise false
*/
function check($msg=true){
// compare provided string with decrypted captcha
$rand = PMA_blowfish_decrypt($_REQUEST[$this->field_sec],auth_cookiesalt());
if($this->getConf('mode') == 'math'){
$code = $this->_generateMATH($this->_fixedIdent(),$rand);
$code = $code[1];
}else{
$code = $this->_generateCAPTCHA($this->_fixedIdent(),$rand);
}
if(!$_REQUEST[$this->field_sec] ||
!$_REQUEST[$this->field_in] ||
strtoupper($_REQUEST[$this->field_in]) != $code ||
trim($_REQUEST[$this->field_hp]) !== ''
){
if($msg) msg($this->getLang('testfailed'),-1);
return false;
}
return true;
}
/**
* Build a semi-secret fixed string identifying the current page and user
*
* This string is always the same for the current user when editing the same
* page revision, but only for one day. Editing a page before midnight and saving
* after midnight will result in a failed CAPTCHA once, but makes sure it can
* not be reused which is especially important for the registration form where the
* $ID usually won't change.
*/
function _fixedIdent(){
global $ID;
$lm = @filemtime(wikiFN($ID));
$td = date('Y-m-d');
return auth_browseruid().
auth_cookiesalt().
$ID.$lm.$td;
}
/**
* Generates a random 5 char string
*
* @param $fixed string - the fixed part, any string
* @param $rand float - some random number between 0 and 1
* @return string
*/
function _generateCAPTCHA($fixed,$rand){
$fixed = hexdec(substr(md5($fixed),5,5)); // use part of the md5 to generate an int
$numbers = md5($rand * $fixed); // combine both values
// now create the letters
$code = '';
for($i=0;$i<10;$i+=2){
$code .= chr(floor(hexdec($numbers[$i].$numbers[$i+1])/10) + 65);
}
return $code;
}
/**
* Create a mathematical task and its result
*
* @param $fixed string - the fixed part, any string
* @param $rand float - some random number between 0 and 1
* @return string
*/
function _generateMATH($fixed, $rand){
$fixed = hexdec(substr(md5($fixed),5,5)); // use part of the md5 to generate an int
$numbers = md5($rand * $fixed); // combine both values
// first letter is the operator (+/-)
$op = (hexdec($numbers[0]) > 8 ) ? -1 : 1;
$num = array(hexdec($numbers[1].$numbers[2]), hexdec($numbers[3]));
// we only want positive results
if(($op < 0) && ($num[0] < $num[1])) rsort($num);
// prepare result and task text
$res = $num[0] + ($num[1] * $op);
$task = $num[0] . (($op < 0) ? ' - ' : ' + ') . $num[1] . ' = ?';
return array($task, $res);
}
/**
* Create a CAPTCHA image
*/
function _imageCAPTCHA($text){
$w = $this->getConf('width');
$h = $this->getConf('height');
$fonts = glob(dirname(__FILE__).'/fonts/*.ttf');
// create a white image
$img = imagecreate($w, $h);
imagecolorallocate($img, 255, 255, 255);
// add some lines as background noise
for ($i = 0; $i < 30; $i++) {
$color = imagecolorallocate($img,rand(100, 250),rand(100, 250),rand(100, 250));
imageline($img,rand(0,$w),rand(0,$h),rand(0,$w),rand(0,$h),$color);
}
// draw the letters
for ($i = 0; $i < strlen($text); $i++){
$font = $fonts[array_rand($fonts)];
$color = imagecolorallocate($img, rand(0, 100), rand(0, 100), rand(0, 100));
$size = rand(floor($h/1.8),floor($h*0.7));
$angle = rand(-35, 35);
$x = ($w*0.05) + $i * floor($w*0.9/5);
$cheight = $size + ($size*0.5);
$y = floor($h / 2 + $cheight / 3.8);
imagettftext($img, $size, $angle, $x, $y, $color, $font, $text[$i]);
}
header("Content-type: image/png");
imagepng($img);
imagedestroy($img);
}
}