Captcha opensource securimage (version 3)-----------------------------------------
Url     : http://codes-sources.commentcamarche.net/source/54396-captcha-opensource-securimage-version-3Auteur  : aventurier19Date    : 07/08/2013
Licence :
=========

Ce document intitul  Captcha opensource securimage (version 3)  issu de CommentCaMarche
(codes-sources.commentcamarche.net) est mis  disposition sous les termes de
la licence Creative Commons. Vous pouvez copier, modifier des copies de cette
source, dans les conditions fixes par la licence, tant que cette note
apparat clairement.

Description :
=============

Suite &agrave; une demande pour int&eacute;grer un captcha dans un de mes script
s, je suis parti &agrave; la recherche d'un facile &agrave; int&eacute;grer faut
e de ne savoir en faire un moi-m&ecirc;me.
<br />
<br />Je suis tomb&eacute; s
ur SECURIMAGE qui est un captcha opensource et qui est tr&egrave;s personnalisab
le.
<br />
<br />Vous demander pourquoi je partage un script qui n'est pas de 
moi est une bonne question ; n&eacute;anmoins j'ai plusieurs r&eacute;ponses :

<br />- pour faire d&eacute;couvrir ce script facile d'utilisation &agrave; ceux
 qui ne le connaissait pas,
<br />- aider les d&eacute;butants (j'en suis un au
ssi) &agrave; utiliser un captcha,
<br />- fournir une traduction de la doc dis
ponible sur le site faite par moi.
<br />
<br />Vous trouverai dans l'archive 
un fichier permettant de tester la configuration de votre serveur web et ainsi v
&eacute;rifier si vous pouvez utiliser le captcha.
<br />
<br />N'h&eacute;sit
ez pas &agrave; donner votre avis.
<br />Bonne prog
<br />
<br />Je joins en 
source le fichier securimage.php qui est la base de ce captcha.
<br /><a name='
source-exemple'></a><h2> Source / Exemple : </h2>

<br /><pre class='code' data
-mode='basic'>
&lt;?php

// error_reporting(E_ALL); ini_set('display_errors',
 1); // uncomment this line for debugging

/**

<ul> <li> Project:     Secur
image: A PHP class for creating and managing form CAPTCHA images&lt;br /&gt;
</
li> <li> File:        securimage.php&lt;br /&gt;</li></ul>
 *

<ul> <li> Copy
right (c) 2011, Drew Phillips
</li> <li> All rights reserved.
</li> <li> 
</l
i> <li> Redistribution and use in source and binary forms, with or without modif
ication,
</li> <li> are permitted provided that the following conditions are me
t:
</li> <li> 
</li> <li>  - Redistributions of source code must retain the ab
ove copyright notice,
</li> <li>    this list of conditions and the following d
isclaimer.
</li> <li>  - Redistributions in binary form must reproduce the abov
e copyright notice,
</li> <li>    this list of conditions and the following dis
claimer in the documentation
</li> <li>    and/or other materials provided with
 the distribution.
</li> <li> 
</li> <li> THIS SOFTWARE IS PROVIDED BY THE COP
YRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
</li> <li> AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</li> <li> IMPLIED WARR
ANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</li> <li> ARE D
ISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
</li> <li>
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
</li> <li>
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
</li> <li
> SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
</li
> <li> INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

</li> <li> CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
E)
</li> <li> ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVIS
ED OF THE
</li> <li> POSSIBILITY OF SUCH DAMAGE.</li></ul>
 *

<ul> <li> Any
 modifications to the library should be indicated clearly in the source code
</
li> <li> to inform users that the changes are not a part of the original softwar
e.&lt;br /&gt;&lt;br /&gt;</li></ul>
 *

<ul> <li> If you found this script u
seful, please take a quick moment to rate it.&lt;br /&gt;
</li> <li> <a href='h
ttp://www.hotscripts.com/rate/49400.html' target='_blank'>http://www.hotscripts.
com/rate/49400.html</a>  Thanks.</li></ul>
 *

<ul> <li> @link <a href='http:
//www.phpcaptcha.org' target='_blank'>http://www.phpcaptcha.org</a> Securimage P
HP CAPTCHA
</li> <li> @link <a href='http://www.phpcaptcha.org/latest.zip' targ
et='_blank'>http://www.phpcaptcha.org/latest.zip</a> Download Latest Version
</
li> <li> @link <a href='http://www.phpcaptcha.org/Securimage_Docs/' target='_bla
nk'>http://www.phpcaptcha.org/Securimage_Docs/</a> Online Documentation
</li> <
li> @copyright 2011 Drew Phillips
</li> <li> @author Drew Phillips &lt;drew@dre
w-phillips.com&gt;
</li> <li> @version 3.0.1 (January 2012)
</li> <li> @packag
e Securimage</li></ul>
 *

<ul> <li>/</li></ul>

/**
 ChangeLog

 3.1
 
- Bugfix: removed use of deprecated variable in addSignature method that would c
ause errors with display_errors on
 
 3.0
 - Rewrite class using PHP5 OOP
 -
 Remove support for GD fonts, require FreeType
 - Remove support for multi-colo
r codes
 - Add option to make codes case-sensitive
 - Add namespaces to suppor
t multiple captchas on a single page or page specific captchas
 - Add option to
 show simple math problems instead of codes
 - Remove support for mp3 files due
 to vulnerability in decoding mp3 audio files
 - Create new flash file to strea
m wav files instead of mp3
 - Changed to BSD license

 2.0.2
 - Fix pathing 
to make integration into libraries easier (Nathan Phillip Brink ohnobinki@ohnopu
blishing.net)

 2.0.1
 - Add support for browsers with cookies disabled (requ
ires php5, sqlite) maps users to md5 hashed ip addresses and md5 hashed codes fo
r security
 - Add fallback to gd fonts if ttf support is not enabled or font fi
le not found (Mike Challis <a href='http://www.642weather.com/weather/scripts.ph
p)' target='_blank'>http://www.642weather.com/weather/scripts.php)</a>
 - Check
 for previous definition of image type constants (Mike Challis)
 - Fix mime typ
e settings for audio output
 - Fixed color allocation issues with multiple colo
rs and background images, consolidate allocation to one function
 - Ability to 
let codes expire after a given length of time
 - Allow HTML color codes to be p
assed to Securimage_Color (suggested by Mike Challis)

 2.0.0
 - Add mathemat
ical distortion to characters (using code from HKCaptcha)
 - Improved session s
upport
 - Added Securimage_Color class for easier color definitions
 - Add dis
tortion to audio output to prevent binary comparison attack (proposed by Sven &q
uot;SavageTiger&quot; Hagemann [insecurity.nl])
 - Flash button to stream mp3 a
udio (Douglas Walsh www.douglaswalsh.net)
 - Audio output is mp3 format by defa
ult
 - Change font to AlteHaasGrotesk by yann le coroller
 - Some code cleanup
 

 1.0.4 (unreleased)
 - Ability to output audible codes in mp3 format to st
ream from flash

 1.0.3.1
 - Error reading from wordlist in some cases caused
 words to be cut off 1 letter short

 1.0.3
 - Removed shadow_text from code 
which could cause an undefined property error due to removal from previous versi
on

 1.0.2
 - Audible CAPTCHA Code wav files
 - Create codes from a word lis
t instead of random strings

 1.0
 - Added the ability to use a selected char
acter set, rather than a-z0-9 only.
 - Added the multi-color text option to use
 different colors for each letter.
 - Switched to automatic session handling in
stead of using files for code storage
 - Added GD Font support if ttf support i
s not available.  Can use internal GD fonts or load new ones.
 - Added the abil
ity to set line thickness
 - Added option for drawing arced lines over letters


 - Added ability to choose image type for output

<ul> <li>/</li></ul>

/**


<ul> <li> Securimage CAPTCHA Class.</li></ul>
 *

<ul> <li> @version    3
.0
</li> <li> @package    Securimage
</li> <li> @subpackage classes
</li> <li
> @author     Drew Phillips &lt;drew@drew-phillips.com&gt;</li></ul>
 *

<ul>
 <li>/</li></ul>
class Securimage
{
    // All of the public variables below 
are securimage options
    // They can be passed as an array to the Securimage 
constructor, set below,
    // or set from securimage_show.php and securimage_p
lay.php
    
    /**

<ul>     <li> Renders captcha as a JPEG image
</li>  
   <li> @var int
</li>     <li>/</li></ul>
    const SI_IMAGE_JPEG = 1;
    /
**

<ul>     <li> Renders captcha as a PNG image (default)
</li>     <li> @va
r int
</li>     <li>/</li></ul>
    const SI_IMAGE_PNG  = 2;
    /**

<ul> 
    <li> Renders captcha as a GIF image
</li>     <li> @var int
</li>     <li>
/</li></ul>
    const SI_IMAGE_GIF  = 3;
    
    /**

<ul>     <li> Create
 a normal alphanumeric captcha
</li>     <li> @var int
</li>     <li>/</li></u
l>
    const SI_CAPTCHA_STRING     = 0;
    /**

<ul>     <li> Create a capt
cha consisting of a simple math problem
</li>     <li> @var int
</li>     <li>
/</li></ul>
    const SI_CAPTCHA_MATHEMATIC = 1;
    
    /**

<ul>     <li
> The width of the captcha image
</li>     <li> @var int
</li>     <li>/</li><
/ul>
    public $image_width = 215;
    /**

<ul>     <li> The height of the
 captcha image
</li>     <li> @var int
</li>     <li>/</li></ul>
    public $
image_height = 80;
    /**

<ul>     <li> The type of the image, default = pn
g
</li>     <li> @var int
</li>     <li>/</li></ul>
    public $image_type   
= self::SI_IMAGE_PNG;

    /**

<ul>     <li> The background color of the ca
ptcha
</li>     <li> @var Securimage_Color
</li>     <li>/</li></ul>
    publ
ic $image_bg_color = '#ffffff';
    /**

<ul>     <li> The color of the captc
ha text
</li>     <li> @var Securimage_Color
</li>     <li>/</li></ul>
    pu
blic $text_color     = '#707070';
    /**

<ul>     <li> The color of the lin
es over the captcha
</li>     <li> @var Securimage_Color
</li>     <li>/</li><
/ul>
    public $line_color     = '#707070';
    /**

<ul>     <li> The colo
r of the noise that is drawn
</li>     <li> @var Securimage_Color 
</li>     <
li>/</li></ul>
    public $noise_color    = '#707070';
    
    /**

<ul>  
   <li> How transparent to make the text 0 = completely opaque, 100 = invisible


</li>     <li> @var int
</li>     <li>/</li></ul>
    public $text_transparen
cy_percentage = 50;
    /**

<ul>     <li> Whether or not to draw the text tr
ansparently, true = use transparency, false = no transparency
</li>     <li> @v
ar bool
</li>     <li>/</li></ul>
    public $use_transparent_text         = f
alse;
    
    /**

<ul>     <li> The length of the captcha code
</li>     
<li> @var int
</li>     <li>/</li></ul>
    public $code_length    = 6;
    /
**

<ul>     <li> Whether the captcha should be case sensitive (not recommende
d, use only for maximum protection)
</li>     <li> @var bool
</li>     <li>/</
li></ul>
    public $case_sensitive = false;
    /**

<ul>     <li> The char
acter set to use for generating the captcha code
</li>     <li> @var string
</
li>     <li>/</li></ul>
    public $charset        = 'ABCDEFGHKLMNPRSTUVWYZabcd
efghklmnprstuvwyz23456789';
    /**

<ul>     <li> How long in seconds a capt
cha remains valid, after this time it will not be accepted
</li>     <li> @var 
unknown_type
</li>     <li>/</li></ul>
    public $expiry_time    = 900;
    

    /**

<ul>     <li> The session name securimage should use, only set this
 if your application uses a custom session name
</li>     <li> It is recommende
d to set this value below so it is used by all securimage scripts
</li>     <li
> @var string
</li>     <li>/</li></ul>
    public $session_name   = null;
  
  
    /**

<ul>     <li> true to use the wordlist file, false to generate ra
ndom captcha codes
</li>     <li> @var bool
</li>     <li>/</li></ul>
    pub
lic $use_wordlist   = false;

    /**

<ul>     <li> The level of distortion
, 0.75 = normal, 1.0 = very high distortion
</li>     <li> @var double
</li>  
   <li>/</li></ul>
    public $perturbation = 0.75;
    /**

<ul>     <li> H
ow many lines to draw over the captcha code to increase security
</li>     <li>
 @var int
</li>     <li>/</li></ul>
    public $num_lines    = 8;
    /**


<ul>     <li> The level of noise (random dots) to place on the image, 0-10
</li
>     <li> @var int
</li>     <li>/</li></ul>
    public $noise_level  = 0;
 
   
    /**

<ul>     <li> The signature text to draw on the bottom corner of
 the image
</li>     <li> @var string
</li>     <li>/</li></ul>
    public $i
mage_signature = '';
    /**

<ul>     <li> The color of the signature text

</li>     <li> @var Securimage_Color
</li>     <li>/</li></ul>
    public $sig
nature_color = '#707070';
    /**

<ul>     <li> The path to the ttf font fil
e to use for the signature text, defaults to $ttf_file (AHGBold.ttf)
</li>     
<li> @var string
</li>     <li>/</li></ul>
    public $signature_font;
    

    /**

<ul>     <li> Use an SQLite database to store data (for users that do
 not support cookies)
</li>     <li> @var bool
</li>     <li>/</li></ul>
    
public $use_sqlite_db = false;
    
    /**

<ul>     <li> The type of captc
ha to create, either alphanumeric, or a math problem&lt;br /&gt;
</li>     <li>
 Securimage::SI_CAPTCHA_STRING or Securimage::SI_CAPTCHA_MATHEMATIC
</li>     <
li> @var int
</li>     <li>/</li></ul>
    public $captcha_type  = self::SI_CA
PTCHA_STRING;
    
    /**

<ul>     <li> The captcha namespace, use this if
 you have multiple forms on a single page, blank if you do not use multiple form
s on one page
</li>     <li> @var string
</li>     <li> &lt;code&gt;
</li>   
  <li> &lt;?php
</li>     <li> // in securimage_show.php (create one show scrip
t for each form)
</li>     <li> $img-&gt;namespace = 'contact_form';
</li>    
 <li> 
</li>     <li> // in form validator
</li>     <li> $img-&gt;namespace =
 'contact_form';
</li>     <li> if ($img-&gt;check($code) == true) {
</li>    
 <li>     echo &quot;Valid!&quot;;
</li>     <li>  }
</li>     <li> </pre>
</
li>     <li>/</li></ul>
<br />    public $namespace;
<br />    
<br />    /**


<ul>     <li> The font file to use to draw the captcha code, leave blank for
 default font AHGBold.ttf
</li>     <li> @var string
</li>     <li>/</li></ul>

<br />    public $ttf_file;
<br />    /**

<ul>     <li> The path to the wo
rdlist file to use, leave blank for default words/words.txt
</li>     <li> @var
 string
</li>     <li>/</li></ul>
<br />    public $wordlist_file;
<br />    
/**

<ul>     <li> The directory to scan for background images, if set a rando
m background will be chosen from this folder
</li>     <li> @var string
</li> 
    <li>/</li></ul>
<br />    public $background_directory;
<br />    /**

<
ul>     <li> The path to the SQLite database file to use, if $use_sqlite_databas
e = true, should be chmod 666
</li>     <li> @var string
</li>     <li>/</li><
/ul>
<br />    public $sqlite_database;
<br />    /**

<ul>     <li> The pat
h to the securimage audio directory, can be set in securimage_play.php
</li>   
  <li> @var string
</li>     <li> <pre class='code' data-mode='php'>
</li>    
 <li> $img-&gt;audio_path = '/home/yoursite/public_html/securimage/audio/';
</l
i>     <li> </pre>
</li>     <li>/</li></ul>
<br />    public $audio_path;
<b
r />
<br />    
<br />    
<br />    protected $im;
<br />    protected $tmp
img;
<br />    protected $bgimg;
<br />    protected $iscale = 5;
<br />    


<br />    protected $securimage_path = null;
<br />    
<br />    protected $
code;
<br />    protected $code_display;
<br />    
<br />    protected $capt
cha_code;
<br />    protected $sqlite_handle;
<br />    
<br />    protected 
$gdbgcolor;
<br />    protected $gdtextcolor;
<br />    protected $gdlinecolor
;
<br />    protected $gdsignaturecolor;
<br />    
<br />    /**

<ul>    
 <li> Create a new securimage object, pass options to set in the constructor.&lt
;br /&gt;
</li>     <li> This can be used to display a captcha, play an audible
 captcha, or validate an entry
</li>     <li> @param array $options
</li>     
<li> <pre class='code' data-mode='php'>
</li>     <li> $options = array(
</li>
     <li>     'text_color' =&gt; new Securimage_Color('#013020'),
</li>     <li
>     'code_length' =&gt; 5,
</li>     <li>     'num_lines' =&gt; 5,
</li>    
 <li>     'noise_level' =&gt; 3,
</li>     <li>     'font_file' =&gt; Securimag
e::getPath() . '/custom.ttf'
</li>     <li> );
</li>     <li> 
</li>     <li>
 $img = new Securimage($options);
</li>     <li> </pre>
</li>     <li>/</li></
ul>
<br />    public function __construct($options = array())
<br />    {
<br
 />        $this-&gt;securimage_path = dirname(__FILE__);
<br />        
<br /
>        if (is_array($options) && sizeof($options) &gt; 0) {
<br />           
 foreach($options as $prop =&gt; $val) {
<br />                $this-&gt;$prop 
= $val;
<br />            }
<br />        }
<br />
<br />        $this-&gt;i
mage_bg_color  = $this-&gt;initColor($this-&gt;image_bg_color,  '#ffffff');
<br
 />        $this-&gt;text_color      = $this-&gt;initColor($this-&gt;text_color,
      '#616161');
<br />        $this-&gt;line_color      = $this-&gt;initColor
($this-&gt;line_color,      '#616161');
<br />        $this-&gt;noise_color    
 = $this-&gt;initColor($this-&gt;noise_color,     '#616161');
<br />        $th
is-&gt;signature_color = $this-&gt;initColor($this-&gt;signature_color, '#616161
');
<br />
<br />        if ($this-&gt;ttf_file == null) {
<br />            
$this-&gt;ttf_file = $this-&gt;securimage_path . '/AHGBold.ttf';
<br />        
}
<br />        
<br />        $this-&gt;signature_font = $this-&gt;ttf_file;


<br />        
<br />        if ($this-&gt;wordlist_file == null) {
<br />   
         $this-&gt;wordlist_file = $this-&gt;securimage_path . '/words/words.txt
';
<br />        }
<br />        
<br />        if ($this-&gt;sqlite_database
 == null) {
<br />            $this-&gt;sqlite_database = $this-&gt;securimage_
path . '/database/securimage.sqlite';
<br />        }
<br />        
<br />  
      if ($this-&gt;audio_path == null) {
<br />            $this-&gt;audio_pat
h = $this-&gt;securimage_path . '/audio/';
<br />        }
<br />        
<br
 />        if ($this-&gt;code_length == null || $this-&gt;code_length &lt; 1) {


<br />            $this-&gt;code_length = 6;
<br />        }
<br />        

<br />        if ($this-&gt;perturbation == null || !is_numeric($this-&gt;pertur
bation)) {
<br />            $this-&gt;perturbation = 0.75;
<br />        }
<
br />        
<br />        if ($this-&gt;namespace == null || !is_string($this
-&gt;namespace)) {
<br />            $this-&gt;namespace = 'default';
<br />  
      }
<br />
<br />        // Initialize session or attach to existing
<br 
/>        if ( session_id() == '' ) { // no session has been started yet, which 
is needed for validation
<br />            if ($this-&gt;session_name != null &
& trim($this-&gt;session_name) != '') {
<br />                session_name(trim
($this-&gt;session_name)); // set session name if provided
<br />            }


<br />            session_start();
<br />        }
<br />    }
<br />    
<
br />    /**

<ul>     <li> Return the absolute path to the Securimage directo
ry
</li>     <li> @return string The path to the securimage base directory
</l
i>     <li>/</li></ul>
<br />    public static function getPath()
<br />    {


<br />        return dirname(__FILE__);
<br />    }
<br />    
<br />    /**


<ul>     <li> Used to serve a captcha image to the browser
</li>     <li> @
param string $background_image The path to the background image to use
</li>   
  <li> <pre class='code' data-mode='php'> 
</li>     <li> $img = new Securimage
();
</li>     <li> $img-&gt;code_length = 6;
</li>     <li> $img-&gt;num_lines
   = 5;
</li>     <li> $img-&gt;noise_level = 5;
</li>     <li> 
</li>     <l
i> $img-&gt;show(); // sends the image to browser
</li>     <li> exit;
</li>  
   <li> </pre>
</li>     <li>/</li></ul>
<br />    public function show($backg
round_image = '')
<br />    {
<br />        if($background_image != '' && is_r
eadable($background_image)) {
<br />            $this-&gt;bgimg = $background_i
mage;
<br />        }
<br />
<br />        $this-&gt;doImage();
<br />    }


<br />    
<br />    /**

<ul>     <li> Check a submitted code against the s
tored value
</li>     <li> @param string $code  The captcha code to check
</li
>     <li> <pre class='code' data-mode='php'>
</li>     <li> $code = $_POST['co
de'];
</li>     <li> $img  = new Securimage();
</li>     <li> if ($img-&gt;che
ck($code) == true) {
</li>     <li>     $captcha_valid = true;
</li>     <li> 
} else {
</li>     <li>     $captcha_valid = false;
</li>     <li> }
</li>   
  <li> </pre>
</li>     <li>/</li></ul>
<br />    public function check($code)

<br />    {
<br />        $this-&gt;code_entered = $code;
<br />        $thi
s-&gt;validate();
<br />        return $this-&gt;correct_code;
<br />    }
<b
r />    
<br />    /**

<ul>     <li> Output a wav file of the captcha code t
o the browser
</li>     <li> 
</li>     <li> <pre class='code' data-mode='php'
>
</li>     <li> $img = new Securimage();
</li>     <li> $img-&gt;outputAudioF
ile(); // outputs a wav file to the browser
</li>     <li> exit;
</li>     <li
> </pre>
</li>     <li>/</li></ul>
<br />    public function outputAudioFile()

<br />    {
<br />        $ext = 'wav'; // force wav - mp3 is insecure
<br /
>        
<br />        header(&quot;Content-Disposition: attachment; filename=
\&quot;securimage_audio.{$ext}\&quot;&quot;);
<br />        header('Cache-Contr
ol: no-store, no-cache, must-revalidate');
<br />        header('Expires: Sun, 
1 Jan 2000 12:00:00 GMT');
<br />        header('Last-Modified: ' . gmdate('D, 
d M Y H:i:s') . 'GMT');
<br />        header('Content-type: audio/x-wav');
<br
 />        
<br />        $audio = $this-&gt;getAudibleCode($ext);
<br />
<br
 />        header('Content-Length: ' . strlen($audio));
<br />
<br />        e
cho $audio;
<br />        exit;
<br />    }
<br />    
<br />    /**

<ul>
     <li> The main image drawing routing, responsible for constructing the entir
e image and serving it
</li>     <li>/</li></ul>
<br />    protected function 
doImage()
<br />    {
<br />        if( ($this-&gt;use_transparent_text == tru
e || $this-&gt;bgimg != '') && function_exists('imagecreatetruecolor')) {
<br /
>            $imagecreate = 'imagecreatetruecolor';
<br />        } else {
<br
 />            $imagecreate = 'imagecreate';
<br />        }
<br />        
<
br />        $this-&gt;im     = $imagecreate($this-&gt;image_width, $this-&gt;im
age_height);
<br />        $this-&gt;tmpimg = $imagecreate($this-&gt;image_widt
h * $this-&gt;iscale, $this-&gt;image_height * $this-&gt;iscale);
<br />       
 
<br />        $this-&gt;allocateColors();
<br />        imagepalettecopy($th
is-&gt;tmpimg, $this-&gt;im);
<br />
<br />        $this-&gt;setBackground();


<br />
<br />        $this-&gt;createCode();
<br />
<br />        if ($this-
&gt;noise_level &gt; 0) {
<br />            $this-&gt;drawNoise();
<br />     
   }
<br />        
<br />        $this-&gt;drawWord();
<br />        
<br /
>        if ($this-&gt;perturbation &gt; 0 && is_readable($this-&gt;ttf_file)) {

<br />            $this-&gt;distortedCopy();
<br />        }
<br />
<br /> 
       if ($this-&gt;num_lines &gt; 0) {
<br />            $this-&gt;drawLines(
);
<br />        }
<br />
<br />        if (trim($this-&gt;image_signature) !
= '') {
<br />            $this-&gt;addSignature();
<br />        }
<br />
<
br />        $this-&gt;output();
<br />    }
<br />    
<br />    /**

<ul>
     <li> Allocate the colors to be used for the image
</li>     <li>/</li></ul
>
<br />    protected function allocateColors()
<br />    {
<br />        // 
allocate bg color first for imagecreate
<br />        $this-&gt;gdbgcolor = ima
gecolorallocate($this-&gt;im,
<br />                                           
   $this-&gt;image_bg_color-&gt;r,
<br />                                      
        $this-&gt;image_bg_color-&gt;g,
<br />                                 
             $this-&gt;image_bg_color-&gt;b);
<br />        
<br />        $al
pha = intval($this-&gt;text_transparency_percentage / 100 * 127);
<br />       
 
<br />        if ($this-&gt;use_transparent_text == true) {
<br />          
  $this-&gt;gdtextcolor = imagecolorallocatealpha($this-&gt;im,
<br />         
                                                $this-&gt;text_color-&gt;r,
<br
 />                                                         $this-&gt;text_color
-&gt;g,
<br />                                                         $this-&g
t;text_color-&gt;b,
<br />                                                     
    $alpha);
<br />            $this-&gt;gdlinecolor = imagecolorallocatealpha(
$this-&gt;im,
<br />                                                         $t
his-&gt;line_color-&gt;r,
<br />                                               
          $this-&gt;line_color-&gt;g,
<br />                                   
                      $this-&gt;line_color-&gt;b,
<br />                       
                                  $alpha);
<br />            $this-&gt;gdnoisec
olor = imagecolorallocatealpha($this-&gt;im,
<br />                            
                              $this-&gt;noise_color-&gt;r,
<br />              
                                            $this-&gt;noise_color-&gt;g,
<br />
                                                          $this-&gt;noise_color-
&gt;b,
<br />                                                          $alpha);

<br />        } else {
<br />            $this-&gt;gdtextcolor = imagecoloral
locate($this-&gt;im,
<br />                                                    
$this-&gt;text_color-&gt;r,
<br />                                             
       $this-&gt;text_color-&gt;g,
<br />                                      
              $this-&gt;text_color-&gt;b);
<br />            $this-&gt;gdlineco
lor = imagecolorallocate($this-&gt;im,
<br />                                  
                  $this-&gt;line_color-&gt;r,
<br />                           
                         $this-&gt;line_color-&gt;g,
<br />                    
                                $this-&gt;line_color-&gt;b);
<br />            
$this-&gt;gdnoisecolor = imagecolorallocate($this-&gt;im,
<br />               
                                           $this-&gt;noise_color-&gt;r,
<br /> 
                                                         $this-&gt;noise_color-&
gt;g,
<br />                                                          $this-&gt
;noise_color-&gt;b);
<br />        }
<br />    
<br />        $this-&gt;gdsig
naturecolor = imagecolorallocate($this-&gt;im,
<br />                          
                           $this-&gt;signature_color-&gt;r,
<br />             
                                        $this-&gt;signature_color-&gt;g,
<br />
                                                     $this-&gt;signature_color-&
gt;b);
<br />
<br />    }
<br />    
<br />    /**

<ul>     <li> The the 
background color, or background image to be used
</li>     <li>/</li></ul>
<br
 />    protected function setBackground()
<br />    {
<br />        // set bac
kground color of image by drawing a rectangle since imagecreatetruecolor doesn't
 set a bg color
<br />        imagefilledrectangle($this-&gt;im, 0, 0,
<br /> 
                            $this-&gt;image_width, $this-&gt;image_height,
<br 
/>                             $this-&gt;gdbgcolor);
<br />        imagefilledr
ectangle($this-&gt;tmpimg, 0, 0,
<br />                             $this-&gt;i
mage_width * $this-&gt;iscale, $this-&gt;image_height * $this-&gt;iscale,
<br /
>                             $this-&gt;gdbgcolor);
<br />    
<br />        i
f ($this-&gt;bgimg == '') {
<br />            if ($this-&gt;background_director
y != null && 
<br />                is_dir($this-&gt;background_directory) &&

<br />                is_readable($this-&gt;background_directory))
<br />      
      {
<br />                $img = $this-&gt;getBackgroundFromDirectory();
<
br />                if ($img != false) {
<br />                    $this-&gt;b
gimg = $img;
<br />                }
<br />            }
<br />        }
<br
 />        
<br />        if ($this-&gt;bgimg == '') {
<br />            retur
n;
<br />        }
<br />
<br />        $dat = @getimagesize($this-&gt;bgimg)
;
<br />        if($dat == false) { 
<br />            return;
<br />        
}
<br />
<br />        switch($dat[2]) {
<br />            case 1:  $newim = 
@imagecreatefromgif($this-&gt;bgimg); break;
<br />            case 2:  $newim 
= @imagecreatefromjpeg($this-&gt;bgimg); break;
<br />            case 3:  $new
im = @imagecreatefrompng($this-&gt;bgimg); break;
<br />            default: re
turn;
<br />        }
<br />
<br />        if(!$newim) return;
<br />
<br /
>        imagecopyresized($this-&gt;im, $newim, 0, 0, 0, 0,
<br />             
            $this-&gt;image_width, $this-&gt;image_height,
<br />              
           imagesx($newim), imagesy($newim));
<br />    }
<br />    
<br />  
  /**

<ul>     <li> Scan the directory for a background image to use
</li>  
   <li>/</li></ul>
<br />    protected function getBackgroundFromDirectory()
<
br />    {
<br />        $images = array();
<br />
<br />        if ( ($dh = 
opendir($this-&gt;background_directory)) !== false) {
<br />            while (
($file = readdir($dh)) !== false) {
<br />                if (preg_match('/(jpg
|gif|png)$/i', $file)) $images[] = $file;
<br />            }
<br />
<br />  
          closedir($dh);
<br />
<br />            if (sizeof($images) &gt; 0) 
{
<br />                return rtrim($this-&gt;background_directory, '/') . '/'
 . $images[rand(0, sizeof($images)-1)];
<br />            }
<br />        }
<
br />
<br />        return false;
<br />    }
<br />    
<br />    /**

<u
l>     <li> Generates the code or math problem and saves the value to the sessio
n
</li>     <li>/</li></ul>
<br />    protected function createCode()
<br /> 
   {
<br />        $this-&gt;code = false;
<br />
<br />        switch($this-
&gt;captcha_type) {
<br />            case self::SI_CAPTCHA_MATHEMATIC:
<br />
            {
<br />                $signs = array('+', '-', 'x');
<br />     
           $left  = rand(1, 10);
<br />                $right = rand(1, 5);
<b
r />                $sign  = $signs[rand(0, 2)];
<br />                
<br />
                switch($sign) {
<br />                    case 'x': $c = $left 
* $right; break;
<br />                    case '-': $c = $left - $right; break
;
<br />                    default:  $c = $left + $right; break;
<br />      
          }
<br />                
<br />                $this-&gt;code       
  = $c;
<br />                $this-&gt;code_display = &quot;$left $sign $right
&quot;;
<br />                break;
<br />            }
<br />            

<br />            default:
<br />            {
<br />                if ($this
-&gt;use_wordlist && is_readable($this-&gt;wordlist_file)) {
<br />            
        $this-&gt;code = $this-&gt;readCodeFromFile();
<br />                }


<br />
<br />                if ($this-&gt;code == false) {
<br />           
         $this-&gt;code = $this-&gt;generateCode($this-&gt;code_length);
<br />
                }
<br />                
<br />                $this-&gt;code_
display = $this-&gt;code;
<br />                $this-&gt;code         = ($this
-&gt;case_sensitive) ? $this-&gt;code : strtolower($this-&gt;code);
<br />     
       } // default
<br />        }
<br />        
<br />        $this-&gt;sa
veData();
<br />    }
<br />    
<br />    /**

<ul>     <li> Draws the cap
tcha code on the image
</li>     <li>/</li></ul>
<br />    protected function 
drawWord()
<br />    {
<br />        $width2  = $this-&gt;image_width * $this-
&gt;iscale;
<br />        $height2 = $this-&gt;image_height * $this-&gt;iscale;

<br />         
<br />        if (!is_readable($this-&gt;ttf_file)) {
<br />
            imagestring($this-&gt;im, 4, 10, ($this-&gt;image_height / 2) - 5, '
Failed to load TTF font file!', $this-&gt;gdtextcolor);
<br />        } else {


<br />            if ($this-&gt;perturbation &gt; 0) {
<br />                $
font_size = $height2 * .4;
<br />                $bb = imageftbbox($font_size, 
0, $this-&gt;ttf_file, $this-&gt;code_display);
<br />                $tx = $bb
[4] - $bb[0];
<br />                $ty = $bb[5] - $bb[1];
<br />             
   $x  = floor($width2 / 2 - $tx / 2 - $bb[0]);
<br />                $y  = rou
nd($height2 / 2 - $ty / 2 - $bb[1]);
<br />
<br />                imagettftext
($this-&gt;tmpimg, $font_size, 0, $x, $y, $this-&gt;gdtextcolor, $this-&gt;ttf_f
ile, $this-&gt;code_display);
<br />            } else {
<br />               
 $font_size = $this-&gt;image_height * .4;
<br />                $bb = imageftb
box($font_size, 0, $this-&gt;ttf_file, $this-&gt;code_display);
<br />         
       $tx = $bb[4] - $bb[0];
<br />                $ty = $bb[5] - $bb[1];
<br
 />                $x  = floor($this-&gt;image_width / 2 - $tx / 2 - $bb[0]);
<
br />                $y  = round($this-&gt;image_height / 2 - $ty / 2 - $bb[1]);

<br />
<br />                imagettftext($this-&gt;im, $font_size, 0, $x, $y
, $this-&gt;gdtextcolor, $this-&gt;ttf_file, $this-&gt;code_display);
<br />   
         }
<br />        }
<br />        
<br />        // DEBUG
<br />     
   //$this-&gt;im = $this-&gt;tmpimg;
<br />        //$this-&gt;output();
<br 
/>        
<br />    }
<br />    
<br />    /**

<ul>     <li> Copies the c
aptcha image to the final image with distortion applied
</li>     <li>/</li></u
l>
<br />    protected function distortedCopy()
<br />    {
<br />        $nu
mpoles = 3; // distortion factor
<br />        // make array of poles AKA attra
ctor points
<br />        for ($i = 0; $i &lt; $numpoles; ++ $i) {
<br />     
       $px[$i]  = rand($this-&gt;image_width  * 0.2, $this-&gt;image_width  * 0.
8);
<br />            $py[$i]  = rand($this-&gt;image_height * 0.2, $this-&gt;i
mage_height * 0.8);
<br />            $rad[$i] = rand($this-&gt;image_height * 
0.2, $this-&gt;image_height * 0.8);
<br />            $tmp     = ((- $this-&gt;
frand()) * 0.15) - .15;
<br />            $amp[$i] = $this-&gt;perturbation * $
tmp;
<br />        }
<br />        
<br />        $bgCol = imagecolorat($this
-&gt;tmpimg, 0, 0);
<br />        $width2 = $this-&gt;iscale * $this-&gt;image_
width;
<br />        $height2 = $this-&gt;iscale * $this-&gt;image_height;
<br
 />        imagepalettecopy($this-&gt;im, $this-&gt;tmpimg); // copy palette to 
final image so text colors come across
<br />        // loop over $img pixels, 
take pixels from $tmpimg with distortion field
<br />        for ($ix = 0; $ix 
&lt; $this-&gt;image_width; ++ $ix) {
<br />            for ($iy = 0; $iy &lt; 
$this-&gt;image_height; ++ $iy) {
<br />                $x = $ix;
<br />      
          $y = $iy;
<br />                for ($i = 0; $i &lt; $numpoles; ++ $i
) {
<br />                    $dx = $ix - $px[$i];
<br />                    $
dy = $iy - $py[$i];
<br />                    if ($dx == 0 && $dy == 0) {
<br 
/>                        continue;
<br />                    }
<br />        
            $r = sqrt($dx * $dx + $dy * $dy);
<br />                    if ($r 
&gt; $rad[$i]) {
<br />                        continue;
<br />               
     }
<br />                    $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i])
;
<br />                    $x += $dx * $rscale;
<br />                    $y 
+= $dy * $rscale;
<br />                }
<br />                $c = $bgCol;

<br />                $x *= $this-&gt;iscale;
<br />                $y *= $this
-&gt;iscale;
<br />                if ($x &gt;= 0 && $x &lt; $width2 && $y &gt;
= 0 && $y &lt; $height2) {
<br />                    $c = imagecolorat($this-&g
t;tmpimg, $x, $y);
<br />                }
<br />                if ($c != $bg
Col) { // only copy pixels of letters to preserve any background image
<br />  
                  imagesetpixel($this-&gt;im, $ix, $iy, $c);
<br />            
    }
<br />            }
<br />        }
<br />    }
<br />    
<br />    
/**

<ul>     <li> Draws distorted lines on the image
</li>     <li>/</li></u
l>
<br />    protected function drawLines()
<br />    {
<br />        for ($l
ine = 0; $line &lt; $this-&gt;num_lines; ++ $line) {
<br />            $x = $th
is-&gt;image_width * (1 + $line) / ($this-&gt;num_lines + 1);
<br />           
 $x += (0.5 - $this-&gt;frand()) * $this-&gt;image_width / $this-&gt;num_lines;


<br />            $y = rand($this-&gt;image_height * 0.1, $this-&gt;image_heigh
t * 0.9);
<br />            
<br />            $theta = ($this-&gt;frand() - 0
.5) * M_PI * 0.7;
<br />            $w = $this-&gt;image_width;
<br />        
    $len = rand($w * 0.4, $w * 0.7);
<br />            $lwid = rand(0, 2);
<br
 />            
<br />            $k = $this-&gt;frand() * 0.6 + 0.2;
<br />  
          $k = $k * $k * 0.5;
<br />            $phi = $this-&gt;frand() * 6.28
;
<br />            $step = 0.5;
<br />            $dx = $step * cos($theta);


<br />            $dy = $step * sin($theta);
<br />            $n = $len / $st
ep;
<br />            $amp = 1.5 * $this-&gt;frand() / ($k + 5.0 / $len);
<br 
/>            $x0 = $x - 0.5 * $len * cos($theta);
<br />            $y0 = $y -
 0.5 * $len * sin($theta);
<br />            
<br />            $ldx = round(-
 $dy * $lwid);
<br />            $ldy = round($dx * $lwid);
<br />            

<br />            for ($i = 0; $i &lt; $n; ++ $i) {
<br />                $x 
= $x0 + $i * $dx + $amp * $dy * sin($k * $i * $step + $phi);
<br />            
    $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i * $step + $phi);
<br />     
           imagefilledrectangle($this-&gt;im, $x, $y, $x + $lwid, $y + $lwid, $t
his-&gt;gdlinecolor);
<br />            }
<br />        }
<br />    }
<br />
    
<br />    /**

<ul>     <li> Draws random noise on the image
</li>     
<li>/</li></ul>
<br />    protected function drawNoise()
<br />    {
<br />  
      if ($this-&gt;noise_level &gt; 10) {
<br />            $noise_level = 10;

<br />        } else {
<br />            $noise_level = $this-&gt;noise_level
;
<br />        }
<br />
<br />        $t0 = microtime(true);
<br />        

<br />        $noise_level *= 125; // an arbitrary number that works well on a
 1-10 scale
<br />        
<br />        $points = $this-&gt;image_width * $th
is-&gt;image_height * $this-&gt;iscale;
<br />        $height = $this-&gt;image
_height * $this-&gt;iscale;
<br />        $width  = $this-&gt;image_width * $th
is-&gt;iscale;
<br />        for ($i = 0; $i &lt; $noise_level; ++$i) {
<br />
            $x = rand(10, $width);
<br />            $y = rand(10, $height);
<
br />            $size = rand(7, 10);
<br />            if ($x - $size &lt;= 0 
&& $y - $size &lt;= 0) continue; // dont cover 0,0 since it is used by imagedist
ortedcopy
<br />            imagefilledarc($this-&gt;tmpimg, $x, $y, $size, $si
ze, 0, 360, $this-&gt;gdnoisecolor, IMG_ARC_PIE);
<br />        }
<br />      
  
<br />        $t1 = microtime(true);
<br />        
<br />        $t = $t1
 - $t0;
<br />        
<br />        /*
<br />        // DEBUG
<br />       
 imagestring($this-&gt;tmpimg, 5, 25, 30, &quot;$t&quot;, $this-&gt;gdnoisecolor
);
<br />        header('content-type: image/png');
<br />        imagepng($th
is-&gt;tmpimg);
<br />        exit;

<ul>        <li>/</li></ul>
<br />    }

<br />    
<br />    /**

<ul>    <li> Print signature text on image
</li>
    <li>/</li></ul>
<br />    protected function addSignature()
<br />    { 

<br />        $bbox = imagettfbbox(10, 0, $this-&gt;signature_font, $this-&gt;im
age_signature);
<br />        $textlen = $bbox[2] - $bbox[0];
<br />        $x
 = $this-&gt;image_width - $textlen - 5;
<br />        $y = $this-&gt;image_hei
ght - 3;
<br />             
<br />        imagettftext($this-&gt;im, 10, 0, $
x, $y, $this-&gt;gdsignaturecolor, $this-&gt;signature_font, $this-&gt;image_sig
nature); 
<br />    }
<br />    
<br />    /**

<ul>     <li> Sends the app
ropriate image and cache headers and outputs image to the browser
</li>     <li
>/</li></ul>
<br />    protected function output()
<br />    {
<br />        
header(&quot;Expires: Mon, 26 Jul 1997 05:00:00 GMT&quot;);
<br />        heade
r(&quot;Last-Modified: &quot; . gmdate(&quot;D, d M Y H:i:s&quot;) . &quot;GMT&q
uot;);
<br />        header(&quot;Cache-Control: no-store, no-cache, must-reval
idate&quot;);
<br />        header(&quot;Cache-Control: post-check=0, pre-check
=0&quot;, false);
<br />        header(&quot;Pragma: no-cache&quot;);
<br />  
      
<br />        switch ($this-&gt;image_type) {
<br />            case se
lf::SI_IMAGE_JPEG:
<br />                header(&quot;Content-Type: image/jpeg&
quot;);
<br />                imagejpeg($this-&gt;im, null, 90);
<br />       
         break;
<br />            case self::SI_IMAGE_GIF:
<br />             
   header(&quot;Content-Type: image/gif&quot;);
<br />                imagegif(
$this-&gt;im);
<br />                break;
<br />            default:
<br />
                header(&quot;Content-Type: image/png&quot;);
<br />            
    imagepng($this-&gt;im);
<br />                break;
<br />        }
<br 
/>        
<br />        imagedestroy($this-&gt;im);
<br />        exit();
<b
r />    }
<br />    
<br />    /**

<ul>     <li> Gets the code and returns 
the binary audio file for the stored captcha code
</li>     <li> @param string 
$format WAV only
</li>     <li>/</li></ul>
<br />    protected function getAud
ibleCode($format = 'wav')
<br />    {
<br />        // override any format oth
er than wav for now
<br />        // this is due to security issues with MP3 fi
les
<br />        $format  = 'wav';
<br />        
<br />        $letters = a
rray();
<br />        $code    = $this-&gt;getCode();
<br />
<br />        if
 ($code == '') {
<br />            $this-&gt;createCode();
<br />            $
code = $this-&gt;getCode();
<br />        }
<br />
<br />        for($i = 0; 
$i &lt; strlen($code); ++$i) {
<br />            $letters[] = $code{$i};
<br /
>        }
<br />        
<br />        if ($format == 'mp3') {
<br />       
     return $this-&gt;generateMP3($letters);
<br />        } else {
<br />    
        return $this-&gt;generateWAV($letters);
<br />        }
<br />    }
<
br />
<br />    /**

<ul>     <li> Gets a captcha code from a wordlist
</li>
     <li>/</li></ul>
<br />    protected function readCodeFromFile()
<br />   
 {
<br />        $fp = @fopen($this-&gt;wordlist_file, 'rb');
<br />        if
 (!$fp) return false;
<br />
<br />        $fsize = filesize($this-&gt;wordlis
t_file);
<br />        if ($fsize &lt; 128) return false; // too small of a lis
t to be effective
<br />
<br />        fseek($fp, rand(0, $fsize - 64), SEEK_S
ET); // seek to a random position of file from 0 to filesize-64
<br />        $
data = fread($fp, 64); // read a chunk from our random position
<br />        f
close($fp);
<br />        $data = preg_replace(&quot;/\r?\n/&quot;, &quot;\n&qu
ot;, $data);
<br />
<br />        $start = @strpos($data, &quot;\n&quot;, rand
(0, 56)) + 1; // random start position
<br />        $end   = @strpos($data, &q
uot;\n&quot;, $start);          // find end of word
<br />        
<br />     
   if ($start === false) {
<br />            return false;
<br />        } els
e if ($end === false) {
<br />            $end = strlen($data);
<br />        
}
<br />
<br />        return strtolower(substr($data, $start, $end - $start))
; // return a line of the file
<br />    }
<br />    
<br />    /**

<ul>  
   <li> Generates a random captcha code from the set character set
</li>     <l
i>/</li></ul>
<br />    protected function generateCode()
<br />    {
<br /> 
       $code = '';
<br />
<br />        for($i = 1, $cslen = strlen($this-&gt;
charset); $i &lt;= $this-&gt;code_length; ++$i) {
<br />            $code .= $t
his-&gt;charset{rand(0, $cslen - 1)};
<br />        }
<br />        
<br />  
      //return 'testing';  // debug, set the code to given string
<br />       
 
<br />        return $code;
<br />    }
<br />    
<br />    /**

<ul>  
   <li> Checks the entered code against the value stored in the session or sqlit
e database, handles case sensitivity
</li>     <li> Also clears the stored code
s if the code was entered correctly to prevent re-use
</li>     <li>/</li></ul>

<br />    protected function validate()
<br />    {
<br />        $code = $t
his-&gt;getCode();
<br />        // returns stored code, or an empty string if 
no stored code was found
<br />        // checks the session and sqlite databas
e if enabled
<br />        
<br />        if ($this-&gt;case_sensitive == fals
e && preg_match('/[A-Z]/', $code)) {
<br />            // case sensitive was se
t from securimage_show.php but not in class
<br />            // the code saved
 in the session has capitals so set case sensitive to true
<br />            $t
his-&gt;case_sensitive = true;
<br />        }
<br />        
<br />        $
code_entered = trim( (($this-&gt;case_sensitive) ? $this-&gt;code_entered
<br /
>                                                       : strtolower($this-&gt;c
ode_entered))
<br />                        );
<br />        $this-&gt;correct
_code = false;
<br />        
<br />        if ($code != '') {
<br />        
    if ($code == $code_entered) {
<br />                $this-&gt;correct_code 
= true;
<br />                $_SESSION['securimage_code_value'][$this-&gt;name
space] = '';
<br />                $_SESSION['securimage_code_ctime'][$this-&gt
;namespace] = '';
<br />                $this-&gt;clearCodeFromDatabase();
<br
 />            }
<br />        }
<br />    }
<br />    
<br />    /**

<ul
>     <li> Return the code from the session or sqlite database if used.  If none
 exists yet, an empty string is returned
</li>     <li>/</li></ul>
<br />    p
rotected function getCode()
<br />    {
<br />        $code = '';
<br />     
   
<br />        if (isset($_SESSION['securimage_code_value'][$this-&gt;namesp
ace]) &&
<br />         trim($_SESSION['securimage_code_value'][$this-&gt;names
pace]) != '') {
<br />            if ($this-&gt;isCodeExpired(
<br />         
   $_SESSION['securimage_code_ctime'][$this-&gt;namespace]) == false) {
<br /> 
               $code = $_SESSION['securimage_code_value'][$this-&gt;namespace];


<br />            }
<br />        } else if ($this-&gt;use_sqlite_db == true &
& function_exists('sqlite_open')) {
<br />            // no code in session - m
ay mean user has cookies turned off
<br />            $this-&gt;openDatabase();

<br />            $code = $this-&gt;getCodeFromDatabase();
<br />        } el
se { /* no code stored in session or sqlite database, validation will fail */ }


<br />        
<br />        return $code;
<br />    }
<br />    
<br />   
 /**

<ul>     <li> Save data to session namespace and database if used
</li>
     <li>/</li></ul>
<br />    protected function saveData()
<br />    {
<br 
/>        $_SESSION['securimage_code_value'][$this-&gt;namespace] = $this-&gt;co
de;
<br />        $_SESSION['securimage_code_ctime'][$this-&gt;namespace] = tim
e();
<br />        
<br />        $this-&gt;saveCodeToDatabase();
<br />    }

<br />    
<br />    /**

<ul>     <li> Saves the code to the sqlite databa
se
</li>     <li>/</li></ul>
<br />    protected function saveCodeToDatabase()

<br />    {
<br />        $success = false;
<br />        
<br />        $t
his-&gt;openDatabase();
<br />        
<br />        if ($this-&gt;use_sqlite_
db && $this-&gt;sqlite_handle !== false) {
<br />            $ip      = $_SERVE
R['REMOTE_ADDR'];
<br />            $time    = time();
<br />            $code
    = $_SESSION['securimage_code_value'][$this-&gt;namespace]; // if cookies are
 disabled the session still exists at this point
<br />            $success = s
qlite_query($this-&gt;sqlite_handle,
<br />                                    
&quot;INSERT OR REPLACE INTO codes(ip, code, namespace, created)
<br />        
                            VALUES('$ip', '$code', '{$this-&gt;namespace}', $tim
e)&quot;);
<br />        }
<br />        
<br />        return $success !== f
alse;
<br />    }
<br />    
<br />    /**

<ul>     <li> Open sqlite datab
ase
</li>     <li>/</li></ul>
<br />    protected function openDatabase()
<br
 />    {
<br />        $this-&gt;sqlite_handle = false;
<br />        
<br />
        if ($this-&gt;use_sqlite_db && function_exists('sqlite_open')) {
<br />
            $this-&gt;sqlite_handle = sqlite_open($this-&gt;sqlite_database, 066
6, $error);
<br />            
<br />            if ($this-&gt;sqlite_handle !
== false) {
<br />                $res = sqlite_query($this-&gt;sqlite_handle, 
&quot;PRAGMA table_info(codes)&quot;);
<br />                if (sqlite_num_row
s($res) == 0) {
<br />                    sqlite_query($this-&gt;sqlite_handle,
 &quot;CREATE TABLE codes (ip VARCHAR(32) PRIMARY KEY, code VARCHAR(32) NOT NULL
, namespace VARCHAR(32) NOT NULL, created INTEGER)&quot;);
<br />              
  }
<br />            }
<br />            
<br />            return $this-&gt
;sqlite_handle != false;
<br />        }
<br />        
<br />        return 
$this-&gt;sqlite_handle;
<br />    }
<br />    
<br />    /**

<ul>     <li
> Get a code from the sqlite database for ip address
</li>     <li>/</li></ul>


<br />    protected function getCodeFromDatabase()
<br />    {
<br />        
$code = '';
<br />
<br />        if ($this-&gt;use_sqlite_db && $this-&gt;sqli
te_handle !== false) {
<br />            $ip = $_SERVER['REMOTE_ADDR'];
<br />
            $ns = sqlite_escape_string($this-&gt;namespace);
<br />
<br />    
        $res = sqlite_query($this-&gt;sqlite_handle, &quot;SELECT * FROM codes W
HERE ip = '$ip' AND namespace = '$ns'&quot;);
<br />            if ($res && sql
ite_num_rows($res) &gt; 0) {
<br />                $res = sqlite_fetch_array($r
es);
<br />
<br />                if ($this-&gt;isCodeExpired($res['created'])
 == false) {
<br />                    $code = $res['code'];
<br />           
     }
<br />            }
<br />        }
<br />        return $code;
<br /
>    }
<br />    
<br />    /**

<ul>     <li> Remove an entered code from t
he database
</li>     <li>/</li></ul>
<br />    protected function clearCodeFr
omDatabase()
<br />    {
<br />        if (is_resource($this-&gt;sqlite_handle
)) {
<br />            $ip = $_SERVER['REMOTE_ADDR'];
<br />            $ns = 
sqlite_escape_string($this-&gt;namespace);
<br />            
<br />          
  sqlite_query($this-&gt;sqlite_handle, &quot;DELETE FROM codes WHERE ip = '$ip'
 AND namespace = '$ns'&quot;);
<br />        }
<br />    }
<br />    
<br />
    /**

<ul>     <li> Deletes old codes from sqlite database
</li>     <li>/
</li></ul>
<br />    protected function purgeOldCodesFromDatabase()
<br />    
{
<br />        if ($this-&gt;use_sqlite_db && $this-&gt;sqlite_handle !== fals
e) {
<br />            $now   = time();
<br />            $limit = (!is_numeri
c($this-&gt;expiry_time) || $this-&gt;expiry_time &lt; 1) ? 86400 : $this-&gt;ex
piry_time;
<br />            
<br />            sqlite_query($this-&gt;sqlite_
handle, &quot;DELETE FROM codes WHERE $now - created &gt; $limit&quot;);
<br />
        }
<br />    }
<br />    
<br />    /**

<ul>     <li> Checks to see
 if the captcha code has expired and cannot be used
</li>     <li> @param unkno
wn_type $creation_time
</li>     <li>/</li></ul>
<br />    protected function 
isCodeExpired($creation_time)
<br />    {
<br />        $expired = true;
<br 
/>        
<br />        if (!is_numeric($this-&gt;expiry_time) || $this-&gt;ex
piry_time &lt; 1) {
<br />            $expired = false;
<br />        } else i
f (time() - $creation_time &lt; $this-&gt;expiry_time) {
<br />            $exp
ired = false;
<br />        }
<br />        
<br />        return $expired;

<br />    }
<br />    
<br />    /**

<ul>     <li> 
</li>     <li> Generat
e an MP3 audio file of the captcha image
</li>     <li> 
</li>     <li> @depre
cated 3.0
</li>     <li>/</li></ul>
<br />    protected function generateMP3()

<br />    {
<br />        return false;
<br />    }
<br />    
<br />    /
**

<ul>     <li> Generate a wav file given the $letters in the code
</li>   
  <li> @todo Add ability to merge 2 sound files together to have random backgrou
nd sounds
</li>     <li> @param array $letters
</li>     <li> @return string T
he binary contents of the wav file
</li>     <li>/</li></ul>
<br />    protect
ed function generateWAV($letters)
<br />    {
<br />        $data_len       = 
0;
<br />        $files          = array();
<br />        $out_data       = ''
;
<br />        $out_channels   = 0;
<br />        $out_samplert   = 0;
<br /
>        $out_bpersample = 0;
<br />        $numSamples     = 0;
<br />       
 $removeChunks   = array('LIST', 'DISP', 'NOTE');
<br />
<br />        for ($i
 = 0; $i &lt; sizeof($letters); ++$i) {
<br />            $letter   = $letters[
$i];
<br />            $filename = $this-&gt;audio_path . strtoupper($letter) .
 '.wav';
<br />            $file     = array();
<br />            $data     = 
@file_get_contents($filename);
<br />            
<br />            if ($data 
=== false) {
<br />                // echo &quot;Failed to read $filename&quot;
;
<br />                return $this-&gt;audioError();
<br />            }
<b
r />
<br />            $header = substr($data, 0, 36);
<br />            $info
   = unpack('NChunkID/VChunkSize/NFormat/NSubChunk1ID/'
<br />                 
           .'VSubChunk1Size/vAudioFormat/vNumChannels/'
<br />                 
           .'VSampleRate/VByteRate/vBlockAlign/vBitsPerSample',
<br />         
                    $header);
<br />            
<br />            $dataPos   
     = strpos($data, 'data');
<br />            $out_channels   = $info['NumCha
nnels'];
<br />            $out_samplert   = $info['SampleRate'];
<br />      
      $out_bpersample = $info['BitsPerSample'];
<br />            
<br />     
       if ($dataPos === false) {
<br />                // wav file with no data
?
<br />                // echo &quot;Failed to find DATA segment in $filename&
quot;;
<br />                return $this-&gt;audioError();
<br />            
}
<br />            
<br />            if ($info['AudioFormat'] != 1) {
<br /
>                // only work with PCM audio
<br />                // echo &quo
t;$filename was not PCM audio, only PCM is supported&quot;;
<br />             
   return $this-&gt;audioError();
<br />            }
<br />            
<br 
/>            if ($info['SubChunk1Size'] != 16 && $info['SubChunk1Size'] != 18) 
{
<br />                // probably unsupported extension
<br />              
  // echo &quot;Bad SubChunk1Size in $filename - Size was {$info['SubChunk1Size'
]}&quot;;
<br />                return $this-&gt;audioError();
<br />         
   }
<br />            
<br />            if ($info['SubChunk1Size'] &gt; 16) 
{
<br />                $header .= substr($data, 36, $info['SubChunk1Size'] - 1
6);
<br />            }
<br />            
<br />            if ($i == 0) {

<br />                // create the final file's header, size will be adjusted l
ater
<br />                $out_data = $header . 'data';
<br />            }

<br />            
<br />            $removed = 0;
<br />            
<br /> 
           foreach($removeChunks as $chunk) {
<br />                $chunkPos =
 strpos($data, $chunk);
<br />                if ($chunkPos !== false) {
<br /
>                    $listSize = unpack('VSize', substr($data, $chunkPos + 4, 4)
);
<br />                    
<br />                    $data = substr($data, 
0, $chunkPos) .
<br />                            substr($data, $chunkPos + 8 +
 $listSize['Size']);
<br />                            
<br />                
    $removed += $listSize['Size'] + 8;
<br />                }
<br />         
   }
<br />            
<br />            $dataSize    = unpack('VSubchunk2Siz
e', substr($data, $dataPos + 4, 4));
<br />            $dataSize['Subchunk2Size
'] -= $removed;
<br />            $out_data   .= substr($data, $dataPos + 8, $d
ataSize['Subchunk2Size'] * ($out_bpersample / 8));
<br />            $numSample
s += $dataSize['Subchunk2Size'];
<br />        }
<br />
<br />        $filesi
ze  = strlen($out_data);
<br />        $chunkSize = $filesize - 8;
<br />     
   $dataCSize = $numSamples;
<br />        
<br />        $out_data = substr_r
eplace($out_data, pack('V', $chunkSize), 4, 4);
<br />        $out_data = subst
r_replace($out_data, pack('V', $numSamples), 40 + ($info['SubChunk1Size'] - 16),
 4);
<br />
<br />        $this-&gt;scrambleAudioData($out_data, 'wav');
<br 
/>        
<br />        return $out_data;
<br />    }
<br />    
<br />    
/**

<ul>     <li> Randomizes the audio data to add noise and prevent binary r
ecognition
</li>     <li> @param string $data  The binary audio file data
</li
>     <li> @param string $format The format of the sound file (wav only)
</li> 
    <li>/</li></ul>
<br />    protected function scrambleAudioData(&$data, $for
mat)
<br />    {
<br />        $start = strpos($data, 'data') + 4; // look for
 &quot;data&quot; indicator
<br />        if ($start === false) $start = 44;  /
/ if not found assume 44 byte header
<br />         
<br />        $start  += 
rand(1, 4); // randomize starting offset
<br />        $datalen = strlen($data)
 - $start;
<br />        $step    = 1;
<br />        
<br />        for ($i =
 $start; $i &lt; $datalen; $i += $step) {
<br />            $ch = ord($data{$i}
);
<br />            if ($ch == 0 || $ch == 255) continue;
<br />            


<br />            if ($ch &lt; 16 || $ch &gt; 239) {
<br />                $ch
 += rand(-6, 6);
<br />            } else {
<br />                $ch += rand(
-12, 12);
<br />            }
<br />            
<br />            if ($ch &l
t; 0) $ch = 0; else if ($ch &gt; 255) $ch = 255;
<br />
<br />            $dat
a{$i} = chr($ch);
<br />            
<br />            $step = rand(1,4);
<br
 />        }
<br />
<br />        return $data;
<br />    }
<br />    
<br 
/>    /**

<ul>     <li> Return a wav file saying there was an error generatin
g file
</li>     <li> 
</li>     <li> @return string The binary audio contents

</li>     <li>/</li></ul>
<br />    protected function audioError()
<br />  
  {
<br />        return @file_get_contents(dirname(__FILE__) . '/audio/error.w
av');
<br />    }
<br />    
<br />    function frand()
<br />    {
<br /> 
       return 0.0001 * rand(0,9999);
<br />    }
<br />    
<br />    /**


<ul>     <li> Convert an html color code to a Securimage_Color
</li>     <li> @
param string $color
</li>     <li> @param Securimage_Color $default The defalt 
color to use if $color is invalid
</li>     <li>/</li></ul>
<br />    protecte
d function initColor($color, $default)
<br />    {
<br />        if ($color ==
 null) {
<br />            return new Securimage_Color($default);
<br />      
  } else if (is_string($color)) {
<br />            try {
<br />              
  return new Securimage_Color($color);
<br />            } catch(Exception $e) 
{
<br />                return new Securimage_Color($default);
<br />         
   }
<br />        } else if (is_array($color) && sizeof($color) == 3) {
<br /
>            return new Securimage_Color($color[0], $color[1], $color[2]);
<br 
/>        } else {
<br />            return new Securimage_Color($default);
<b
r />        }
<br />    }
<br />}
<br />
<br />/**

<ul> <li> Color object
 for Securimage CAPTCHA</li></ul>
<br /> *

<ul> <li> @version 3.0
</li> <li
> @since 2.0
</li> <li> @package Securimage
</li> <li> @subpackage classes</li
></ul>
<br /> *

<ul> <li>/</li></ul>
<br />class Securimage_Color
<br />{


<br />    public $r;
<br />    public $g;
<br />    public $b;
<br />
<br /
>    /**

<ul>     <li> Create a new Securimage_Color object.&lt;br /&gt;
</l
i>     <li> Constructor expects 1 or 3 arguments.&lt;br /&gt;
</li>     <li> Wh
en passing a single argument, specify the color using HTML hex format,&lt;br /&g
t;
</li>     <li> when passing 3 arguments, specify each RGB component (from 0-
255) individually.&lt;br /&gt;
</li>     <li> $color = new Securimage_Color('#0
080FF') or &lt;br /&gt;
</li>     <li> $color = new Securimage_Color(0, 128, 25
5)
</li>     <li> 
</li>     <li> @param string $color
</li>     <li> @throws
 Exception
</li>     <li>/</li></ul>
<br />    public function __construct($co
lor = '#ffffff')
<br />    {
<br />        $args = func_get_args();
<br />   
     
<br />        if (sizeof($args) == 0) {
<br />            $this-&gt;r = 
255;
<br />            $this-&gt;g = 255;
<br />            $this-&gt;b = 255;

<br />        } else if (sizeof($args) == 1) {
<br />            // set based
 on html code
<br />            if (substr($color, 0, 1) == '#') {
<br />     
           $color = substr($color, 1);
<br />            }
<br />            


<br />            if (strlen($color) != 3 && strlen($color) != 6) {
<br />    
            throw new InvalidArgumentException(
<br />                  'Invali
d HTML color code passed to Securimage_Color'
<br />                );
<br /> 
           }
<br />            
<br />            $this-&gt;constructHTML($col
or);
<br />        } else if (sizeof($args) == 3) {
<br />            $this-&g
t;constructRGB($args[0], $args[1], $args[2]);
<br />        } else {
<br />   
         throw new InvalidArgumentException(
<br />              'Securimage_Co
lor constructor expects 0, 1 or 3 arguments; ' . sizeof($args) . ' given'
<br /
>            );
<br />        }
<br />    }
<br />    
<br />    /**

<ul>
     <li> Construct from an rgb triplet
</li>     <li> @param int $red The red 
component, 0-255
</li>     <li> @param int $green The green component, 0-255
<
/li>     <li> @param int $blue The blue component, 0-255
</li>     <li>/</li></
ul>
<br />    protected function constructRGB($red, $green, $blue)
<br />    {

<br />        if ($red &lt; 0)     $red   = 0;
<br />        if ($red &gt; 25
5)   $red   = 255;
<br />        if ($green &lt; 0)   $green = 0;
<br />      
  if ($green &gt; 255) $green = 255;
<br />        if ($blue &lt; 0)    $blue  
= 0;
<br />        if ($blue &gt; 255)  $blue  = 255;
<br />        
<br />  
      $this-&gt;r = $red;
<br />        $this-&gt;g = $green;
<br />        $t
his-&gt;b = $blue;
<br />    }
<br />    
<br />    /**

<ul>     <li> Cons
truct from an html hex color code
</li>     <li> @param string $color
</li>   
  <li>/</li></ul>
<br />    protected function constructHTML($color)
<br />   
 {
<br />        if (strlen($color) == 3) {
<br />            $red   = str_rep
eat(substr($color, 0, 1), 2);
<br />            $green = str_repeat(substr($col
or, 1, 1), 2);
<br />            $blue  = str_repeat(substr($color, 2, 1), 2);


<br />        } else {
<br />            $red   = substr($color, 0, 2);
<br /
>            $green = substr($color, 2, 2);
<br />            $blue  = substr($
color, 4, 2); 
<br />        }
<br />        
<br />        $this-&gt;r = hex
dec($red);
<br />        $this-&gt;g = hexdec($green);
<br />        $this-&gt
;b = hexdec($blue);
<br />    }
<br />}
<br />&lt;/code&gt;
<br /><a name='c
onclusion'></a><h2> Conclusion : </h2>

<br />Il n'y a pas de ?&gt; &agrave; la
 fin de la source car cette page est int&eacute;gr&eacute; dans un script php pa
r exemple gr&acirc;ce &agrave; la fonction include(&quot;&quot;);
<br />
<br /
>Vous pouvez t&eacute;l&eacute;charger la derni&egrave;re version &agrave; cette
 adresse : <a href='http://www.phpcaptcha.org/download/' target='_blank'>http://
www.phpcaptcha.org/download/</a>
<br />Copiez tous les fichiers du dossier de l
'archive t&eacute;l&eacute;charg&eacute;e dans le dossier securimage (avec &eacu
te;crasement/remplacement des anciens fichiers) du script utilis&eacute;.
<br /
>
<br />Attention : si vous avez personnalis&eacute; le fichier securimage_show
.php, faites-en une sauvegarde avant !
<br />
<br />Ce script a &eacute;t&eacu
te; int&eacute;grer dans le formulaire avec le choix du contact disponible &agra
ve; cette adresse <a href='http://www.phpcs.com/codes/FORMULAIRE-CHOIX-MULTI-CON
TACT-VALIDE-XHTML-TRANSITIONAL_52679.aspx' target='_blank'>http://www.phpcs.com/
codes/FORMULAIRE-CHOIX-MULTI-CONTACT-VALIDE-XHTML-TRANSITIONAL_52679.aspx</a>
