|
RWCaptcha (anti-bot / code overtypen)
Auteur: Tuinstoel
- 05 november 2010 - 09:54 - Gekeurd door: Koen
- Hits: 1427 - Aantal punten:
(0 stemmen)
Dit scriptje maakt het welbekende plaatje dat er voor zorgt dat op websites formulieren niet worden ingevuld door bots. Met andere woorden je moet hier dus een code overtypen.
Ik heb de code voorzien van commentaar dus dan kun je precies zien wat er gewijzigd kan worden en wat niet. Het is verder ook plug and play, dus het moet in principe gewoon direct werken.
Let op dat je de .rar gewoon downloadt, want daar zitten de fonts (arial.ttf en georgia.ttf) bij in. Als je dat niet doet moet je er zelf voor zorgen.
|
| Code: |
RWCaptcha.php
<?php
/**
* Genereert een CAPTCHA Code die gekke botjesspam moet voorkomen in
* bijvoorbeeld gastenboeken.
*
* @author René Willemsen (rene@renewillemsen.nl)
* @version 1.0 (2010-11-05)
*/
class RWCaptcha {
/* Algemene instellingen */
private $iHeight = 51; // Hoogte van het plaatje
private $iWidth = 201; // Breedte van het plaatje
private $aBackground = array('red'=>255,'green'=>255,'blue'=>255); // Kleur van de achtergrond in te stellen van 0 tot 255
private $sTokens = 'abcdefghjikmnlopqrstuvwxyz'; // Reeks tekens die kunnen voorkomen. Wees verstandig en doe geen gekke dingen zoals ö of een 0 (nul), dit verwart.
private $iLength = 6; // Lengte van de te genereren string
/* Afblijven */
private $rImage;
private $sCode;
/* Text instellingen */
private $aFont = array('arial.ttf','georgia.ttf'); //,'calibri.ttf','georgia.ttf'); // Locatie van de font
private $aTextColorRange = array('min'=>0,'max'=>150); // Mogelijke kleuren van de letters (verschilt per letter) Zorg voor voldoende contrast.
private $iFontSize = 24; // Grootte van de fontsize. Er zit volgensmij een beperking op tot ongeveer 18pt
private $iAngleMin = -30; // Minimale hoek (mag negatief zijn) waarop een letter staat
private $iAngleMax = 30; // Maximale hoek
/* Achtergrondraster */
private $bRaster = true; // False voor als er geen raster weergegeven moet worden
private $aRasterColor = array('red'=>200,'green'=>200,'blue'=>200); // Kleur van dit raster.
private $iSpacingRow = 10; // Ruimte per rij (over de Y-as)
private $iSpacingCol = 10; // Ruimte per kolom (over de X-as)
/* Achtergrondcirkels */
private $bCirkel = true;
private $aCirkelColor = array('min'=>150,'max'=>255);
private $iCirkelAantal = 30;
/* Hier beneden hoef je in principe niets meer aan te passen */
public function __construct() {
if(extension_loaded('gd') && function_exists('gd_info')) {
// GD Library aanwezig als het goed is...
if($this->iFontSize >= $this->iHeight|| ($this->iLength*$this->iFontSize*0.5) > $this->iWidth) {
// De fontsize is te groot ten opzichte van de ruimte die ie nodigt heeft. Dus stoppen
// Resulteert in een kruisje ;-)
exit;
}
else {
putenv('GDFONTPATH=' . realpath('.'));
// putenv is nodig voor lastige servers... ;-)
$this->generateCode();
$this->startImage();
$this->generateBackground();
$this->writeText();
$this->finalizeImage();
}
}
else {
exit;
}
}
/* Aanmaken van de afbeelding, de .php wijsmaken dat ie 'n PNG is */
private function startImage() {
header("Content-Type: image/png");
$this->rImage = ImageCreate($this->iWidth,$this->iHeight);
}
/* Afsluiten van het GD-proces */
private function finalizeImage() {
ImagePng($this->rImage);
imagedestroy($this->rImage);
}
/* Achtergrond een kleur geven en evt. invulling */
private function generateBackground() {
//blaat
$rBackground = imagecolorallocate($this->rImage, $this->aBackground['red'],$this->aBackground['green'],$this->aBackground['blue']);
ImageFill($this->rImage,0,0,$rBackground);
if($this->bRaster) {
$this->generateRaster();
}
if($this->bCirkel) {
$this->generateCirkel();
}
}
/* Voor het maken van een raster */
private function generateRaster() {
$rColor = imagecolorallocate($this->rImage, $this->aRasterColor['red'],$this->aRasterColor['green'],$this->aRasterColor['blue']);
// horizontal
for($iHor = 0;$iHor<$this->iHeight;$iHor+=$this->iSpacingCol) {
imageline($this->rImage, 0,$iHor, $this->iWidth, $iHor, $rColor);
}
for($iVer = 0;$iVer<$this->iWidth;$iVer+=$this->iSpacingRow) {
imageline($this->rImage, $iVer, 0, $iVer, $this->iHeight, $rColor);
}
// vertical
}
private function generateCirkel() {
for($iCirk = 0;$iCirk<$this->iCirkelAantal;$iCirk++) {
$iSize = rand(10,100);
$rColor = imagecolorallocate($this->rImage, rand($this->aCirkelColor['min'],$this->aCirkelColor['max']), rand($this->aCirkelColor['min'],$this->aCirkelColor['max']), rand($this->aCirkelColor['min'],$this->aCirkelColor['max']));
imagearc($this->rImage, rand(0,$this->iWidth), rand(0,$this->iHeight), $iSize, $iSize,0, 360, $rColor);
}
}
/* Het daadwerkelijk printen van de text */
private function writeText() {
$iMaximumStartFromLeft = $this->iWidth*0.2;
// Uitvogelen wat de maximale positie mag zijn ten opzichte van (0,Y)
$iLocationFromLeft = rand(10,$iMaximumStartFromLeft);
// X-positie eerste letter
$iLocationFromTop = rand($this->iHeight-($this->iHeight*0.2),$this->iHeight-($this->iHeight*0.5));
// Y-positie eerste letter
$iAngle = rand($this->iAngleMin,$this->iAngleMax);
// Hoek v/d 1e letter
for($iLoop=0;$iLoop<strlen($this->sCode);$iLoop++) {
$rColor = imagecolorallocate($this->rImage, rand($this->aTextColorRange['min'],$this->aTextColorRange['max']),rand($this->aTextColorRange['min'],$this->aTextColorRange['max']),rand($this->aTextColorRange['min'],$this->aTextColorRange['max']));
imagefttext($this->rImage, 28, $iAngle, $iLocationFromLeft, $iLocationFromTop, $rColor, $this->aFont[rand(0,(count($this->aFont)-1))], substr($this->sCode,$iLoop,1));
/* Letterinstellingen opnieuw instellen */
$iLocationFromLeft = $iLocationFromLeft + $this->iFontSize;
$iLocationFromTop = rand($this->iHeight-($this->iHeight*0.2),$this->iHeight-($this->iHeight*0.5));
$iAngle = rand($this->iAngleMin,$this->iAngleMax);
}
}
/* De code genereren */
private function generateCode() {
$sString = '';
for($iLoop=0;$iLoop<$this->iLength;$iLoop++) {
$iStart = rand(0,strlen($this->sTokens));
$sString .= substr($this->sTokens,$iStart,1);
}
$this->sCode = $sString;
$this->setCodeInSession();
}
/* Beetje overbodige functie eigenlijk */
private function setCodeInSession() {
$_SESSION['sCode'] = $this->sCode;
}
}
/* Heel belangrijk:
* -Nieuwe sessie starten (!!!)
* -Nieuwe instantie van de Captcha aanmaken
*/
session_start();
$r = new RWCaptcha();
?>
<?php /** * Genereert een CAPTCHA Code die gekke botjesspam moet voorkomen in * bijvoorbeeld gastenboeken. * * @author René Willemsen (rene@renewillemsen.nl) * @version 1.0 (2010-11-05) */ class RWCaptcha { /* Algemene instellingen */ private $iHeight = 51; // Hoogte van het plaatje private $iWidth = 201; // Breedte van het plaatje private $aBackground = array('red'=>255,'green'=>255,'blue'=>255); // Kleur van de achtergrond in te stellen van 0 tot 255 private $sTokens = 'abcdefghjikmnlopqrstuvwxyz'; // Reeks tekens die kunnen voorkomen. Wees verstandig en doe geen gekke dingen zoals ö of een 0 (nul), dit verwart. private $iLength = 6; // Lengte van de te genereren string /* Afblijven */ private $rImage; private $sCode; /* Text instellingen */ private $aFont = array('arial.ttf','georgia.ttf'); //,'calibri.ttf','georgia.ttf'); // Locatie van de font private $aTextColorRange = array('min'=>0,'max'=>150); // Mogelijke kleuren van de letters (verschilt per letter) Zorg voor voldoende contrast. private $iFontSize = 24; // Grootte van de fontsize. Er zit volgensmij een beperking op tot ongeveer 18pt private $iAngleMin = -30; // Minimale hoek (mag negatief zijn) waarop een letter staat private $iAngleMax = 30; // Maximale hoek /* Achtergrondraster */ private $bRaster = true; // False voor als er geen raster weergegeven moet worden private $aRasterColor = array('red'=>200,'green'=>200,'blue'=>200); // Kleur van dit raster. private $iSpacingRow = 10; // Ruimte per rij (over de Y-as) private $iSpacingCol = 10; // Ruimte per kolom (over de X-as) /* Achtergrondcirkels */ private $bCirkel = true; private $aCirkelColor = array('min'=>150,'max'=>255); private $iCirkelAantal = 30; /* Hier beneden hoef je in principe niets meer aan te passen */ public function __construct() { // GD Library aanwezig als het goed is... if($this->iFontSize >= $this->iHeight|| ($this->iLength*$this->iFontSize*0.5) > $this->iWidth) { // De fontsize is te groot ten opzichte van de ruimte die ie nodigt heeft. Dus stoppen // Resulteert in een kruisje ;-) } else { // putenv is nodig voor lastige servers... ;-) $this->generateCode(); $this->startImage(); $this->generateBackground(); $this->writeText(); $this->finalizeImage(); } } else { } } /* Aanmaken van de afbeelding, de .php wijsmaken dat ie 'n PNG is */ private function startImage() { header("Content-Type: image/png"); $this->rImage = ImageCreate($this->iWidth,$this->iHeight); } /* Afsluiten van het GD-proces */ private function finalizeImage() { ImagePng($this->rImage); imagedestroy($this->rImage); } /* Achtergrond een kleur geven en evt. invulling */ private function generateBackground() { //blaat $rBackground = imagecolorallocate($this->rImage, $this->aBackground['red'],$this->aBackground['green'],$this->aBackground['blue']); ImageFill($this->rImage,0,0,$rBackground); if($this->bRaster) { $this->generateRaster(); } if($this->bCirkel) { $this->generateCirkel(); } } /* Voor het maken van een raster */ private function generateRaster() { $rColor = imagecolorallocate($this->rImage, $this->aRasterColor['red'],$this->aRasterColor['green'],$this->aRasterColor['blue']); // horizontal for($iHor = 0;$iHor<$this->iHeight;$iHor+=$this->iSpacingCol) { imageline($this->rImage, 0,$iHor, $this->iWidth, $iHor, $rColor); } for($iVer = 0;$iVer<$this->iWidth;$iVer+=$this->iSpacingRow) { imageline($this->rImage, $iVer, 0, $iVer, $this->iHeight, $rColor); } // vertical } private function generateCirkel() { for($iCirk = 0;$iCirk<$this->iCirkelAantal;$iCirk++) { $rColor = imagecolorallocate ($this->rImage, rand($this->aCirkelColor['min'],$this->aCirkelColor['max']), rand($this->aCirkelColor['min'],$this->aCirkelColor['max']), rand($this->aCirkelColor['min'],$this->aCirkelColor['max'])); imagearc ($this->rImage, rand(0,$this->iWidth), rand(0,$this->iHeight), $iSize, $iSize,0, 360, $rColor); } } /* Het daadwerkelijk printen van de text */ private function writeText() { $iMaximumStartFromLeft = $this->iWidth*0.2; // Uitvogelen wat de maximale positie mag zijn ten opzichte van (0,Y) $iLocationFromLeft = rand(10,$iMaximumStartFromLeft); // X-positie eerste letter $iLocationFromTop = rand($this->iHeight-($this->iHeight*0.2),$this->iHeight-($this->iHeight*0.5)); // Y-positie eerste letter $iAngle = rand($this->iAngleMin,$this->iAngleMax); // Hoek v/d 1e letter for($iLoop=0;$iLoop<strlen($this->sCode);$iLoop++) { $rColor = imagecolorallocate ($this->rImage, rand($this->aTextColorRange['min'],$this->aTextColorRange['max']),rand($this->aTextColorRange['min'],$this->aTextColorRange['max']),rand($this->aTextColorRange['min'],$this->aTextColorRange['max'])); imagefttext ($this->rImage, 28, $iAngle, $iLocationFromLeft, $iLocationFromTop, $rColor, $this->aFont[rand(0,(count($this->aFont)-1))], substr($this->sCode,$iLoop,1)); /* Letterinstellingen opnieuw instellen */ $iLocationFromLeft = $iLocationFromLeft + $this->iFontSize; $iLocationFromTop = rand($this->iHeight-($this->iHeight*0.2),$this->iHeight-($this->iHeight*0.5)); $iAngle = rand($this->iAngleMin,$this->iAngleMax); } } /* De code genereren */ private function generateCode() { $sString = ''; for($iLoop=0;$iLoop<$this->iLength;$iLoop++) { $sString .= substr($this->sTokens,$iStart,1); } $this->sCode = $sString; $this->setCodeInSession(); } /* Beetje overbodige functie eigenlijk */ private function setCodeInSession() { $_SESSION['sCode'] = $this->sCode; } } /* Heel belangrijk: * -Nieuwe sessie starten (!!!) * -Nieuwe instantie van de Captcha aanmaken */ $r = new RWCaptcha(); ?>
Voorbeeld gebruik: <?php
/**
* Voorbeelddocument
*
* @author René Willemsen (rene@renewillemsen.nl)
* @version 1.0 (2010-11-05)
*/
session_start();
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Voorbeeld RWCaptcha</title>
</head>
<body>
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(isset($_SESSION['sCode'])) {
if($_POST['code']==$_SESSION['sCode']) {
echo '<p>De code is juist!</p>';
}
else {
echo '<p>Ben je blind ofzo?</p>';
}
}
else {
echo '<p>Sessie niet gezet. Check je script op session_start() aanwezigheid.</p>';
}
}
?>
<form method="post" action="index.php">
<p><img src="RWCaptcha.php" alt="" /></p>
<p>Type de code over: <input type="text" name="code" /></p>
<p><input type="submit" value="Verzenden" /></p>
</form>
</body>
</html>
<?php /** * Voorbeelddocument * * @author René Willemsen (rene@renewillemsen.nl) * @version 1.0 (2010-11-05) */ ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Voorbeeld RWCaptcha</title> </head> <body> <?php if($_SERVER['REQUEST_METHOD'] == 'POST') { if(isset($_SESSION['sCode'])) { if($_POST['code']==$_SESSION['sCode']) { echo '<p>De code is juist!</p>'; } else { echo '<p>Ben je blind ofzo?</p>'; } } else { echo '<p>Sessie niet gezet. Check je script op session_start() aanwezigheid.</p>'; } } ?> <form method="post" action="index.php"> <p><img src="RWCaptcha.php" alt="" /></p> <p>Type de code over: <input type="text" name="code" /></p> <p><input type="submit" value="Verzenden" /></p> </form> </body> </html>
Download code (.txt)
|
|
|
Stemmen |
| Niet ingelogd |
|