<?php
/**
* cellCaptcha File
* Generates CAPTCHA using Table Cells
* @author Kevin Matory <hide@address.com>
* @version 1.0
* GNU General Public License (Version 2.1, March 7th, 2006)
*
* This program is free software; you can redistribute
* it and/or modify it under the terms of the GNU
* General Public License as published by the Free
* Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/*
1. $c->fillColor = '#000': Set the cell background color or
$c->fillContent = '*' : fill it with some content.
2. Set cell width and height (in pixels) $c->cellW = 4, $c->cellH = 4
3. $c->setMessage() : Set the message. If left empty, a random string
of characters will be generated ( $c->randCharLen : default 5) characters long.
4. echo $c->draw() : Output to the screen.
The other variables are up to you if you wish to use. This class
is simple enough that you can alter to your liking.
*/
class cellCaptcha {
public $finalMsgArray = array();
public $gotLower = true; //If your font contains lowercase letters, the default does
public $randomColor = false; //Do you want to use a random color for the positive captcha cells
public $randomBGColor = false; //If you want a random background color
public $verifyCaseSensative = true; //Self-explanitory
public $useLetterSpacing = false; //Do you want to use letter spacing. Your font may already be spaced.
public $letterSpacing = 1; //How much spacing (cell) you want to use between each letter 1 = 1 cell/td
public $useWordSpacing = true; //Use word spacing?
public $wordSpacing = 6; //How many cells in between each word
public $attributesArray = array(); //For whatever attributes you set
public $fillColor = '#000000'; //Fill Color for positive cells
public $fillContent = ''; //To put content in positive cell
public $negFillColor = 'transparent'; //If you want the negative cells to be something other than transparent
public $negativeContent = ''; //If for some reason you want content negative cells
public $rows;
public $randCharLen = 5; //For random characters generated for captcha
public $cellH = 6; //cell height (which is actually a div inside a td)
public $cellW = 4; //cell width
public $tblBorderSize = 0; //self-explanatory
public $cellpadding = 0; //self-explanatory
public $cellspacing = 1; //self-explanatory
/* attributes */
public $tblBGColor = 'transparent'; //table background color
public $tblClassName = 'cellCaptcha'; //table classname
public $tblID = 'cellCaptcha'; //table classname
public $tblTitle = 'Please type the letters you see'; //self-explanatory
public $tblSummary = ''; //self-explanatory
/*
+ Add more style content. Don't includ the style= or any quotes.
The same goes for for $addedPostCellStyle, $addedNegCellStyle
*/
public $addedTableStyle = 'border:1px solid #ffffff;';
public $tblBGPicUrl = ''; //if you want to add a background pic to table - uses css
public $addedPosCellStyle = 'border-left:1px solid #000000;'; //+ if you want to add more style
public $addedNegCellStyle = 'border-left:1px solid #000000;'; //+ if you want to add more style
/*
The next 2 are somewhat wildcard items. Add a class or id or whatever as a string.
example: $xx->posClassName = someClassName';
*/
public $posClassName = '';
public $negClassName = '';
function cellCaptcha($chars,$matrix){
$this->chars = $chars;
$this->matrix = $matrix;
if( !is_array($chars) || !count($chars) ) die('Argument 1 should be an array and should not be empty!');
if( !is_array($matrix) || !count($matrix) ) die('Argument 2 should be an array and should not be empty!');
}
//This is a random password gen I got off the net somewhere
private function randomChar($len = 8)
{ if(is_numeric($this->randCharLen)) $len = $this->randCharLen;
$vowels = array('a', 'e', 'i', 'o', 'u', 'y');
$confusing = array('I', 'l', '1', 'O', '0');
$replacements = array('A', 'k', '3', 'U', '9');
$choices = array(0 => rand(0, 1), 1 => rand(0, 1), 2 => rand(0, 2));
$parts = array(0 => '', 1 => '', 2 => '');
if ($choices[0]) $parts[0] = rand(1, rand(9,99));
if ($choices[1]) $parts[2] = rand(1, rand(9,99));
$len -= (strlen($parts[0]) + strlen($parts[2]));
for ($i = 0; $i < $len; $i++)
{
if ($i % 2 == 0)
{
do $con = chr(rand(97, 122));
while (in_array($con, $vowels));
$parts[1] .= $con;
}
else
{
$parts[1] .= $vowels[array_rand($vowels)];
}
}
if ($choices[2]) $parts[1] = ucfirst($parts[1]);
if ($choices[2] == 2) $parts[1] = strrev($parts[1]);
$r = $parts[0] . $parts[1] . $parts[2];
$r = str_replace($confusing, $replacements, $r);
return $r;
}
/*
RANDOM COLOR GENERATOR 3
*/
private function random_color(){
mt_srand((double)microtime()*1000000);
$c = '';
while(strlen($c)<6){
$c .= sprintf("%02X", mt_rand(0, 255));
}
return '#'.$c;
}
public function verifyCaptcha($userText){
$userText = trim($userText);
if( $this->verifyCaseSensative )
return ( strcmp($_SESSION['captchaText'], $userText) === 0 );
else
return ( strcasecmp($_SESSION['captchaText'], $userText) === 0 );
}
//instead of multi-level arrays, accumulate bits into rows
//of strings that spell out the word
public function setMessage($msg='') {
$msg = trim($msg);
if( !strlen($msg) ) $msg = $this->randomChar();
if( !$this->gotLower ) $msg = strtoupper($msg);
$maxRows = 0;
$columnCounts = array();
$characters = str_split($msg);
foreach($characters as $char){
$char = trim($char);
$count = count($this->chars[$char]);
if( $count > $maxRows ) $maxRows = $count;
$column = $this->matrix[ $this->chars[$char][0] ];
$columnCounts[ $char ] = strlen($column);
}
$bits = '';
$numZeros = '';
for($j=0;$j<$maxRows;$j++){
for($i=0;$i<count($characters);$i++){
$currChar = trim($characters[$i]); //trim the character
/*
If there is no strlen, then this is whitespace.
Assuming a break between words.
*/
if( !strlen($currChar) && $this->useWordSpacing){
$bits .= str_repeat('0',$this->wordSpacing);
continue;
}else{
/*
Retrieve the array associated with this
character. $currLetter is an array
*/
$currLetter = $this->chars[$currChar];
/*
$tmp is a string. $currLetter[ $j ] is
the VALUE of the $j index in the $currLetter
array. The Value is a number representing
which string in the matrix to return that
will be a part of building the HTML "graphic"
for that character.
*/
$tmp = $this->matrix[ $currLetter[$j] ];
}
/*
If $tmp is not a string, then fill with zeros (whitespace).
It's probably reached more rows than this letter has.
The characters in the font I built all have differing
number of rows and columns.
*/
if( !strlen($tmp) ){
$bits .= str_repeat('0',$columnCounts[$currChar]);
}else
$bits .= $tmp;
/* if you need to add space between the letters */
if( $this->useLetterSpacing ) $bits .= str_repeat('0',$this->letterSpacing);
}
$this->finalMsgArray[ ] = $bits;
$bits = '';
}
if( !isset($_SESSION) ) session_start();
$_SESSION['captchaText'] = $msg;
return $this->finalMsgArray;
}
public function draw($finalMsgArray='') {
$this->tblBGPicUrl = trim($this->tblBGPicUrl);
$this->tblBGColor = trim($this->tblBGColor);
if( is_array($finalMsgArray) && count($finalMsgArray) ) $this->finalMsgArray = $finalMsgArray;
if($this->randomColor || !strlen( trim($this->fillColor) ) ) $this->fillColor = $this->random_color();
$matrix = "\n".'<table align="center" border="'.$this->tblBorderSize.'" cellpadding ="'.$this->cellpadding
.'" cellspacing="'.$this->cellspacing.'"'."\n";
$tableStyle = array();
$tblStyle = '';
if( strlen($this->tblBGPicUrl) ) $tableStyle[ ] = 'background-image:url('.$this->tblBGPicUrl.');';
elseif( strlen($this->tblBGColor) ) $tableStyle[ ] = 'background-color:'.$this->tblBGColor.';';
elseif($this->randomBGColor) $tableStyle[ ] = 'background-color:'.$this->random_color().';';
if( count($tableStyle) ) $tblStyle = implode('',$tableStyle);
if( strlen($this->addedTableStyle) ) $tblStyle .= $this->addedTableStyle;
if( strlen($tblStyle) ) $matrix .= ' style="'.$tblStyle.'"';
$PCN = trim($this->posClassName);
$NCN = trim($this->negClassName);
$this->tblTitle = trim($this->tblTitle);
if( strlen($this->tblTitle) ) $matrix .= ' title="'.$this->tblTitle.'"';
$this->tblSummary = trim($this->tblSummary);
if( strlen($this->tblSummary) ) $matrix .= ' title="'.$this->tblSummary.'"';
$this->tblClassName = trim($this->tblClassName);
if(strlen($this->tblClassName)) $matrix .= ' class="'.$this->tblClassName.'"';
$this->tblID = trim($this->tblID);
if(strlen($this->tblID)) $matrix .= ' id="'.$this->tblID.'"';
$matrix .= '>';
$x=0; $y=0;
foreach($this->finalMsgArray as $line){
$cells = str_split($line);
foreach($cells as $cell){
if($cell){
$column .= "\n".'<td><div id="x'.$x.'y'.$y.'" style="width:'
.$this->cellW.'px;height:'.$this->cellH.'px;background: '
.$this->fillColor.';text-align:center;';
$this->addedPosCellStyle = trim($this->addedPosCellStyle);
if( strlen($this->addedPosCellStyle) ) $column .= $this->addedPosCellStyle;
$column .= '"';
if( strlen($PCN) ) $column .= ' class="'.$PCN.'"';
$column .= '>'.$this->fillContent.'</div></td> ';
}else{
$column .= "\n".'<td><div id="x'.$x.'y'.$y.'" style="width:'
.$this->cellW.'px;height:'.$this->cellH.'px;background: '
.$this->negFillColor.';text-align:center;';
$this->addedNegCellStyle = trim($this->addedNegCellStyle);
if( strlen($this->addedNegCellStyle) ) $column .= $this->addedNegCellStyle;
$column .= '"';
if( strlen($NCN) ) $column .= ' class="'.$NCN.'"';
$column .= '>'.$this->negativeContent.'</div></td> ';
}
$x++;
}
$row .= "\n".'<tr>'.$column."\n".'</tr> ';
$y++;
$column = '';
}
return $matrix.$row.'</table>'."\n";
}
}//end of cellCaptcha class
?>