by:

Das ist der erste Co- Authoren Beitrag auf meiner Seite zum Thema Captchas.
Vielen Dank vorab an: Sereby (http://www.sereby.org/)


Man findet Sie überall und man kommt auch nicht mehr dran vorbei:
Captcha's (Completely Automated Public Turing test to tell Computers and Humans Apart)
Sie werden von Webseiten-Administratoren z.B. bei Kontaktformularen, Shoutboxen oder Downloads verwendet, um sicher zu stellen, dass Bots nicht die Möglichkeit haben die Shoutbox oder ähnliches voll zu spammen oder in einem Downloadbereich dafür zu sorgen, dass nicht unendlich viel Traffic verbraucht wird, weil der Downloadlink tausende Male ausgeführt wird.

Nun zum eigentlichen Code:
Download

zunächst muss die Klasse TCaptcha eingebunden werden um auf die Validierungsfunktionen zuzugreifen
Code


<?
include('captchaTCaptcha.php');
?>
<form action="" method="post" name="111">
    <!-- 
        Einbinden des Captcha's über ein <img> tag.
        Wenn mehrere Captcha's verwendet werden sollen, dann
        müssen Sie die ID verändern!
    -->
    <img src="captcha/show.php?id=1" alt="Sicherheitscode 1" />

    <input type="text" name="captcha_code1" size="13" /> <input type="submit" value="OK" />

    <?
        //code überprüfen
        if (isset($_POST['captcha_code1'])){
            // Validate(* Getippter Code *, * Captcha-ID die verglichen werden soll *) 
            if (TCaptcha::Validate($_POST['captcha_code1'], 1)){
                echo 'Code OK!';
            }else{
                echo 'Falscher Code eingegeben!';
            }
        }
    ?>
</form>


Nun die eigentliche Captcha Klasse

Code

<?php
session_start
();
define('CAPTCHA_SESSION_ID''php_captcha');
define('CAPTCHA_IGNORE_CASE'false);

class 
TCaptcha
{
    var 
$IgnoreCase;
    var 
$CharSet;
    var 
$font;
    var 
$font_size;
    var 
$width;
    var 
$height;
    var 
$bgimg;
    var 
$maxlen;

    public 
$Code;

    public function 
__construct($FontFile './xfiles.ttf'$iWidth 100$iHeight 40)
    {
        
$this->IgnoreCase CAPTCHA_IGNORE_CASE;
        
$this->font       $FontFile;
        
$this->bgimg      './bg.png';
        
$this->maxlen     5;
        
$this->font_size  20;
        
$this->CharSet    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        
$this->SetWidth($iWidth);
        
$this->SetHeight($iHeight);
        
$this->Code '';
    }
    
    function 
SetWidth($iWidth)
    {
        
$this->width $iWidth;
        if (
$iWidth 500$this->width 500;
    }

    function 
SetHeight($iHeight)
    {
        
$this->height $iHeight;
        if (
$iHeight 200$this->height 200;
    }
    
    private function 
randomString($len)
    {
        
//zufallszahl
        
function make_seed()
        {
            list(
$usec $sec) = explode (' 'microtime());
            return (float) 
$sec + ((float) $usec 100000);
        }
        
srand(make_seed());

        
//zufallsstring
        
$str '';
        while (
strlen($str)<$len)
        {
            
$str .= substr($this->CharSet, (rand()%(strlen($this->CharSet))), 1);
        }
           return(
$str);
    }
   
    function 
GenerateCode()
    {
        
//captcha-id
        
$CaptchaID = (is_numeric($_GET['id']) ? $_GET['id'] : '1');
        
        
//code generieren
        
$this->Code $this->randomString($this->maxlen);
        
        
//groß / kleinschreibung beachten?
        
if ($this->IgnoreCase)
        {
            
$this->Code strtoupper($this->Code);
        } 

        
//in die Session schreiben
        
$_SESSION[CAPTCHA_SESSION_ID][$CaptchaID] = $this->Code;
    }

    function 
Create()
    {
        
//Hintergrundbild einlesen
        
$picinfos GetImageSize($this->bgimg);
        
$OldIMG   ImageCreateFromPNG($this->bgimg);
        
        
//größe anpassen
        
$img      ImageCreateTrueColor($this->width$this->height);
        
ImageCopyResized($img,$OldIMG,0,0,0,0,$this->width,$this->height,$picinfos[0],$picinfos[1]);

        
//Farbe der Schrift
        
$color ImageColorAllocate($img000); 
        
        
//ZufallsCode generieren
        
$this->GenerateCode();
        
        
//justierung
        
$spacing = ($this->width $this->maxlen);
        
$t_y_min min($this->height$this->font_size);
        
$t_y   rand($t_y_min 1.2$t_y_min 2.8) + $spacing;
        
$angle rand(0,7);
        
$t_x   rand(5,10);
        
$a     0;

        
//text auf das bild schreiben. Zeichen für Zeichen
        
for ($i 1$i <=$this->maxlen$i++)
        {
            
ImageTTFText($img$this->font_size$angle$t_x$t_y$color$this->font$this->Code{$a});
            
$t_x $t_x $spacing -3;
            
$a++; // nächstes zeichen
        
}
        
        
//bild anzeigen
        
header("Content-type: image/gif");
        
ImageGIF($img);
        
        
//bild freigeben
        
ImageDestroy($img);
    }
    
    function 
Validate($MyCode$ID 1$IgnoreCase CAPTCHA_IGNORE_CASE)
    {
        if (
$IgnoreCase)
        {
            
$MyCode strtoupper($MyCode);
        }

        if (!empty(
$_SESSION[CAPTCHA_SESSION_ID][$ID]) && $MyCode == $_SESSION[CAPTCHA_SESSION_ID][$ID])
        {
            unset(
$_SESSION[CAPTCHA_SESSION_ID][$ID]); //wiederbenutzen vermeiden
            
return true;
        }
        return 
false;
    }
}
?>


Fertig!

Nachtrag von Andreas:

Es gibt auch Möglichkeiten ein Captcha zu umgehen, dies sei an dieser Stelle noch erwähnt. In der Praxis sind die Methoden allerdings eher ineffektiv oder doch etwas kompliziert.

Trotzdem möchte ich kurz auf ein, zwei Möglichkeiten hinweißen.

OCR Software, also Texterkennungssoftware die das Captcha versucht zu interpretieren. Ist in
der Anwendung kompliziert und schwer zu implementieren, aber dennoch der erfolgsversprechendste Ansatz.

Ich habe auch mal von der Möglichkeit gehört, die Captcha bei seiner privaten Seite einzubinden
um seine Besucher die Arbeit erledigen zu lassen indem man sie dazu nötigt die Captchas zu entschlüsseln.
Dies gelingt natürlich nur auf einer interessanten Seite mit viel Traffic.

Andere Varianten nutzen meist nur schlecht programmierte Captcha aus, bei denen z.b. das Lösungswort
in einem hidden field steht...

Vielen Dank Sereby für deinen ersten Beitrag!

Andreas



Name:
Congratulazioni, sito semplice, fuzanonile ed elegante. Girerf2 la tua gentile mail a mia moglie ed a una serie di amiche appassionate di cucina. Gie0 ti rimpiango come Presidente per gli splendidi inviti che ci riservavi. Un caro saluto Stefano.

Name:
Sorry, I do not speak German! But I liked this post.

P.S. Consider adding Google translate widget from:
http://translate.google.com/translate_tools