Am Ende der Seite finden Sie das komplette Beispiel als Download. Systemvoraussetzung
- Linux
- Windows
- PHP 4 >= 4.0.0RC2
- PHP 5
- GD-Bibliothek
(> gd1.6)
- FreeTypeBibliothek
Datei(en)
captcha_math.php, captcha_check.php, captcha_demo_math.php
Problem
Wir haben im vorherigen Beispiel gesehen, wie man unterscheiden kann, ob ein
Webformular durch einen Menschen oder einen Bot ausgefüllt wurde. Dieses
Programm ist schon sehr sicher, man kann es aber noch erweitern. Entscheiden
Sie selbst, ob es für Sie notwendig ist oder nicht.
Lösung
Unser vorheriges Captcha-Beispiel
konnte ein Captcha-Bild
aus Buchstaben
und Zahlen generieren. Wir zeigen Ihnen jetzt, wie Ihr Captcha anfängt zu
rechnen: Dieses Beispiel wird wahllos entweder einen Captcha aus Buchstaben
und Zahlen oder eine Rechenaufgabe liefern.
Wie bereits erwähnt: Halten Sie Ihren Captcha so einfach wie möglich, sodass
ein Mensch ihn lösen kann, eine Maschine aber nur sehr schwer. In unserem
Beispiel werden wir daher nur Rechenaufgaben mit den Zahlen 0 bis 9 heranziehen.
Außerdem bestehen die Rechenaufgaben nur aus Additionen, sodass
sie relativ leicht zu lösen sein sollten.
Nachfolgend sehen Sie noch einmal einen Captcha aus Buchstaben und Zahlen,
danach einen Captcha mit einer Rechenaufgabe.
Abbildung 3.7: Captcha aus Buchstaben und Zahlen
Abbildung 3.8: Captcha mit einer Rechenaufgabe
Wie Sie sehen, sind beide Captchas relativ einfach zu lösen. Der Rechen-Captcha
kann nur einwandfrei gelöst werden, wenn der Besucher als Lösung die Zahl
27 eingibt.
Für dieses Catcha-Beispiel
müssen wir lediglich unsere bereits bekannte
Captcha-Datei
ein wenig umprogrammieren. Die Datei für die Überprüfung der Captchas muss nicht erweitert werden, sie beherrscht bereits jetzt die
Überprüfung beider Varianten.
Wir wollen hier nicht noch einmal alle Funktionen der Captcha-Datei
erklären,
sondern richten unseren Augenmerk nur noch auf die Veränderungen in dieser
Datei.
function mathCaptcha($im,$size,$fileTTF,$imgHeight)
@param resource $im
@param integer $size
@param string $fileTTF
@param integer $imgHeight
@return string $fileName
Neu in unserer bestehenden Datei ist die Funktion mathCaptcha(). Sie erwarten
als Parameter den Zeiger auf das Captcha-Bild,
die Schriftgröße, den
Pfad zu der True-Type-Datei
und die Bildhöhe. Zuerst erzeugen wir für die
Rechenaufgabe die Zahlen im Zahlenraum von 0-9
(128) und durchwürfeln
danach das mit Zahlen gefüllte Array (129).
Sie können natürlich noch einen größeren Zahlenraum nehmen (z. B. 0 bis
20) aber ich rate Ihnen davon ab, denn die Lösung wird dadurch wesentlich
schwieriger.
Nachdem wir die Zahlen erstellt haben, stellen wir die Schriftfarbe für unsere
RGB-Werte
zusammen (131). Wir sollten darauf achten, dass die Zahlen auch
nachher gut lesbar sind und nehmen daher für die Darstellung nur RGB-Werte
im Zahlenraum von 0 bis 120.
Nachdem wir das Array mit den möglichen RGB-Werten
erstellt haben, durchwürfeln
wir auch dieses (132). Mit den RGB-Werten
in dem Array bestimmen
wir dann die Farbe für das Bild (134). Wir sollten für Rechenaufgaben nur eine
Farbe nehmen, im Gegensatz zu den Buchstaben und Zahlen, wo mehrfarbige
Anzeigen erzeugt werden.
Unser Array mit den Zahlen ist bereits durchgewürfelt. Daher können wir
beruhigt nur die ersten fünf Array-Elemente
für die Rechenaufgabe heranziehen.
Zum einen speichern wir die Rechenaufgabe als Text (136), und zum
anderen lösen wir mathematisch die Aufgabe (137). Den Text platzieren (141)
wir nachher auf das Bild, die Lösung wird unsere Funktion zurückgeben (143).
Aus der übermittelten Hash-Summe
und der Lösung bilden wir danach den
Verzeichnisnamen.
Nun müssen wir lediglich noch die Position für den Text definieren, damit die
Rechenaufgabe wahllos in ihrer Höhe unterschiedlich angezeigt wird. Daher
definieren wir auch hier wieder ein Array (138) und durchwürfeln dieses (139).
Zum Schluss schreiben wir den Text auf das Bild (141) und geben die Lösung
unserer Rechenaufgabe zurück.
126:
127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144:
145:
|
function mathCaptcha($im,$size,$fileTTF,$imgHeight)
{
$math = range(0,9); shuffle($math); $mix = range(0,120); shuffle($mix); $color = imagecolorallocate($im,$mix[0],$mix[1],$mix[2]);
$text = "$math[0] + $math[1] + $math[2] + $math[3] + $math[4]"; $fileName = $math[0] + $math[1] + $math[2] + $math[3] + $math[4]; $y = range($size+5,$imgHeight-10); shuffle($y); imagettftext($im, $size, 0, 5, $y[0], $color, $fileTTF,$text); return $fileName; }
|
Beispiel 3.18: captcha_math.php
function makeLetter($im,$size,$fileTTF,$imgHeight,$imgWidth)
@param resource $im
@param integer $size
@param string $fileTTF
@param integer $imgHeight
@param integer $imgWidth
@return string $fileName
Sie sollten den Inhalt dieser Funktion bereits kennen. Wir haben lediglich den
Programmcode für den Aufbau der Buchstaben und Zahlen in eine Funktion
gepackt, damit wir über eine Berechnung (dazu später) entscheiden können,
ob wir einen Rechen-oder
Buchstaben/Zahlen-Captcha
erzeugen sollen.
Wir werden diese Funktion nicht näher erläutern, da wir ihren Inhalt bereits im
vorherigen Beispiel ausgiebig erklärt haben. Sollten Sie nicht mehr genau alle
Aufgaben in dieser Funktion verstehen, schauen Sie noch einmal im vorherigen
Beispiel nach und vertiefen Sie Ihr Wissen.
Wir wollen allerdings kurz die Parameter der Funktion erklären. Die Funktion
erwartet als Parameter den Zeiger auf das Bild, die Schriftgröße, den Pfad zu
der True-Type-Datei,
die Bildhöhe und die Bildbreite. Als Rückgabewert (187)
wird diese Funktion einen Teil (die sechs Buchstaben und Zahlen) des späteren
Dateinamens zurückliefern.
158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175:
176: 177: 178: 179: 180: 181:
182: 183: 184: 185: 186: 187: 188: |
function makeLetter($im,$size,$fileTTF,$imgHeight,$imgWidth)
{
//Wortliste erstellen $alphabet = MakeAlphabet();
// Array des Alphabets durchwürfeln shuffle($alphabet);
$mix = range(0,255); shuffle($mix);
$colors=array( imagecolorallocate($im,$mix[0],$mix[6],$mix[12]), imagecolorallocate($im,$mix[1],$mix[7],$mix[13]), imagecolorallocate($im,$mix[2],$mix[8],$mix[14]), imagecolorallocate($im,$mix[3],$mix[9],$mix[15]), imagecolorallocate($im,$mix[4],$mix[10],$mix[16]), imagecolorallocate($im,$mix[5],$mix[11],$mix[17]));
// Zeichnet die Buchstaben und baut den Dateinamen auf
for($x=0;$x<6;$x++){
$angel = rand(-25,25); $y = rand($size,$imgHeight-20); imagettftext($im, $size, $angel, $next, $y, $colors[$x],
$fileTTF,$alphabet[$x]);
$next += $size + ($imgWidth/$size); $fileName .= $alphabet[$x];
} return $fileName; } |
Beispiel 3.19: captcha_math.php
Auch dieser Programmcode sollte Ihnen bekannt vorkommen. Wir werden
auch hier nicht noch einmal alles erklären, sondern verweisen wieder auf
das vorherige Beispiel. Allerdings gibt es in diesem Programmcode ein paar
Neuerungen, die wir erklären müssen.
Wir haben eine zusätzliche Variable (205) für die Schriftgröße der Rechenaufgabe.
Somit sind Sie in der Lage, die Ausgabe der beiden Möglichkeiten besser
zu steuern. Weiterhin ist ein Bereich (249-252)
dazugekommen, der für die
jeweilige Auswahl der Captchas dienen wird. Anhand der aktuellen Zeit in
Sekunden wird entschieden, welches Captcha geladen werden soll.
Handelt es sich bei den Sekunden um eine gerade Zahl (249), so wird der
Buchstaben/
Zahlen-Captcha
aufgerufen (250). Sollten die Sekunden ungerade
sein (251), wird der mathematische Captcha aufgerufen (252).
190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232:
233:
234: 235:
236:
237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250:
251:
252:
253:
254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: | // TTF-Schrift
// Sie sollten hier unbedingt den absoluten Pfad angeben, da ansonsten // eventuell die TTF-Datei nicht eingebunden werden kann! $fileTTF = '/homepages/29/d151852282/htdocs/kochbuch/bddavinc.ttf';
// Verzeichnis für die Captcha-Bilder (muss Schreibrechte besitzen!) // Ausserdem sollten in diesem Ordner nur die Bilder gespeichert werden // da das Programm in regelmaessigen Abstaenden dieses leert! // Kein abschliessenden Slash benutzen! $captchaDir = 'captchadir';
// Schriftgröße $size = 30;
// Schriftgröße Rechenaufgabe $sizeMath = 22;
//Bildgroesse $imgWidth = 220;//200 $imgHeight = 80;//80
// Farbverlauf RGB-Wert Start und RGB-Wert Ende
$fromRGB = array(
253,
214,
0
);
$toRGB = array(
215,
81,
6
);
// Randfarbe $colorBorder = array(
154,
53,
2
);
header("Content-type: image/png");
$im = @imagecreate($imgWidth, $imgHeight) or die("GD! Initialisierung fehlgeschlagen");
// Definiert die Farbe für den Border $colorB = imagecolorallocate($im,$colorBorder[0],
$colorBorder[1],$colorBorder[2]);
// Erstellt den Farbverlauf $colorRGB = makeGradient($fromRGB,$toRGB,$imgHeight);
for($x=0;$x<$imgHeight;$x++){ $r = $colorRGB['r'][$x]; $g = $colorRGB['g'][$x]; $b = $colorRGB['b'][$x]; $color = imagecolorallocate($im,$r,$g,$b); imageline($im,0,$x,$imgWidth,$x,$color); }
// Hier die Moeglichkeit if(bcmod(time(), 2) == 0) $fileName = makeLetter($im,$size,$fileTTF,
$imgHeight,$imgWidth); else $fileName = mathCaptcha($im,$sizeMath,
$fileTTF,$imgHeight);
// Border erstellen makeBorder($imgWidth,$imgHeight,$im,$colorB);
// Uebermittelter Hash-Wert ueberpruefen if(!preg_match('/^[a-f0-9]{32}$/',$_GET['codeCaptcha'])) $_GET['codeCaptcha'] = md5(microtime());
// Image speichern imagepng($im,$captchaDir.'/'.$_GET['codeCaptcha'].'_'.$fileName.'.png');
imagedestroy($im);
// Bild ausgeben readfile($captchaDir.'/'.$_GET['codeCaptcha'].'_'.$fileName.'.png'); |
Beispiel 3.20: captcha_math.php
Somit haben wir unser bestehendes Captcha-Beispiel
um ein mathematisches
Beispiel erweitert. Wir müssen lediglich in unserem Formular den Image-Tag
verändern. Dieses muss jetzt auf unsere neue Datei zeigen.
1:
|
<img src="captcha_math.php?codeCaptcha=<?php echo $codeCaptcha; ?>">
|
Sie sollten in Ihrem Formular erklären, dass es zwei verschiedene Captcha-Ausgaben
geben kann. Falls Sie das nicht tun, wird der Besucher nicht die
Rechenaufgabe lösen, sondern einfach nur den Rechentext abschreiben. Dieses
würde selbstverständlich nicht zur Lösung des Captchas führen!
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
Download
|
Alle Beispiele als PHP-Datei(en)
Hier haben Sie die Möglichkeit, sich sämtliche auf dieser Seite gezeigten Beispiele als PHP-Dateien direkt downzuloaden.
Umständliches Copy & Paste ist daher nicht mehr notwendig, da alle Beispiele sofort ausprobiert werden können.
Sie haben bei der Auswahl der bereitgestellten Downloads mehrere Möglichkeiten, je nachdem welches Komprimierungsverfahren Sie bevorzugen.
|
Zurück zur Übersichtsseite
|