source: trunk/lib/Captcha.inc.php

Last change on this file was 502, checked in by anonymous, 9 years ago

Many minor fixes during pulso development

File size: 7.7 KB
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * Captcha.inc.php
25 *
26 * ASCII captcha system.
27 *
28 * @author  Quinn Comendant <quinn@strangecode.com>
29 * @version 1.0
30-------------------------------------------------------------------------------------
31// Example.
32
33// Instantiate new Captcha. This automatically generates a new 4-digit captcha number.
34$captcha = new Captcha();
35
36<!-- HTML form for captcha -->
37<label for="sc-captcha"><?php echo _("Reverse Turing Test") ?></label>
38<p class="sc-help"><?php echo _("Please type the following number to prove you are a human. This is a measure to prevent spam robots from submitting this form.") ?></p>
39<pre style="font-size: 0.5em;"><?php $captcha->printAsciiNumber() ?></pre>
40<?php $captcha->printForm() ?>
41
42// Finally, test if the captcha was submitted correctly.
43if (!$captcha->valid()) {
44    // Go back, show error.
45}
46
47// Or if you're using the FormValidator class.
48if (!$captcha->valid()) {
49    $fv->addError('sc-captcha', _("The Captcha you entered is invalid. Please try again."));
50}
51
52-------------------------------------------------------------------------------------
53 */
54class Captcha
55{
56
57    public $secret_key = 'some random seed text for the md5';
58    public $random_number;
59    public $ascii_numbers = array(
60        array(
61            '  #####   ',
62            ' ##   ##  ',
63            '##     ## ',
64            '##     ## ',
65            '##     ## ',
66            ' ##   ##  ',
67            '  #####   ',
68        ), array(
69            '   ##   ',
70            ' ####   ',
71            '   ##   ',
72            '   ##   ',
73            '   ##   ',
74            '   ##   ',
75            ' ###### ',
76        ), array(
77            ' #######  ',
78            '##     ## ',
79            '       ## ',
80            ' #######  ',
81            '##        ',
82            '##        ',
83            '######### ',
84        ), array(
85            ' #######  ',
86            '##     ## ',
87            '       ## ',
88            ' #######  ',
89            '       ## ',
90            '##     ## ',
91            ' #######  ',
92        ), array(
93            '##        ',
94            '##    ##  ',
95            '##    ##  ',
96            '##    ##  ',
97            '######### ',
98            '      ##  ',
99            '      ##  ',
100        ), array(
101            '######## ',
102            '##       ',
103            '##       ',
104            '#######  ',
105            '      ## ',
106            '##    ## ',
107            ' ######  ',
108        ), array(
109            ' #######  ',
110            '##     ## ',
111            '##        ',
112            '########  ',
113            '##     ## ',
114            '##     ## ',
115            ' #######  ',
116        ), array(
117            '######## ',
118            '##    ## ',
119            '    ##   ',
120            '   ##    ',
121            '  ##     ',
122            '  ##     ',
123            '  ##     ',
124        ), array(
125            ' #######  ',
126            '##     ## ',
127            '##     ## ',
128            ' #######  ',
129            '##     ## ',
130            '##     ## ',
131            ' #######  ',
132        ), array(
133            ' #######  ',
134            '##     ## ',
135            '##     ## ',
136            ' ######## ',
137            '       ## ',
138            '##     ## ',
139            ' #######  ',
140        )
141    );
142   
143    /**
144     * Constructor. Initialized new random number.
145     *
146     * @access  public
147     * @author  Quinn Comendant <quinn@strangecode.com>
148     * @since   20 Jan 2006 13:08:22
149     */
150    public function __construct()
151    {
152        $app =& App::getInstance();
153   
154        $this->secret_key = $app->getParam('signing_key');
155        $this->random_number = $this->_getRandomNumber();
156    }
157
158    /**
159     * Print ASCII number.
160     *
161     * @access  public
162     * @param   mixed   $num    Number to convert.
163     * @return  string  ASCII-ized number
164     * @author  Quinn Comendant <quinn@strangecode.com>
165     * @since   07 Dec 2005 21:59:25
166     */
167    public function getAsciiNumber($num=null)
168    {
169        $app =& App::getInstance();
170   
171        if (!isset($num)) {
172            $num = $this->random_number;
173        }
174
175        if (preg_match('/[^\d]/', $num)) {
176            $app->logMsg(sprintf('Bad number: %s', $num), LOG_ERR, __FILE__, __LINE__);
177            return false;
178        }
179
180        // Number must be an array of strings.
181        $num = preg_split('//', strval($num), -1, PREG_SPLIT_NO_EMPTY);
182
183        // All chars must be same height.
184        $output = '';
185        $char_height = sizeof($this->ascii_numbers[0]);
186        for ($i=0; $i<$char_height; $i++) {
187            foreach ($num as $n) {
188                $output .= $this->ascii_numbers[$n][$i];
189            }
190            $output .= "\n";
191        }
192
193        return $output;
194    }
195
196    /**
197     * Prints the captcha ASCII numbers.
198     *
199     * @access  public
200     * @author  Quinn Comendant <quinn@strangecode.com>
201     * @since   07 Dec 2005 22:09:04
202     */
203    public function printAsciiNumber()
204    {
205        $ascii = $this->getAsciiNumber($this->random_number);
206        ?><pre id="sc-captcha"><?php echo $ascii ?></pre><?php
207    }
208
209    /**
210     * Prints a form to enter captcha, including the required hidden hash form.
211     *
212     * @access  public
213     * @author  Quinn Comendant <quinn@strangecode.com>
214     * @since   07 Dec 2005 22:09:04
215     */
216    public function printForm()
217    {
218        $hash = $this->_getMD5key($this->random_number);
219        ?>
220        <input name="sc-captcha-input" id="sc-captcha-input" class="sc-small" type="text" />
221        <input name="sc-captcha-hash" id="sc-captcha-hash" type="hidden" value="<?php echo $hash ?>" />
222        <?php
223    }
224
225    /**
226     * Validate submitted number against ascii captcha.
227     * Regenerate md5 hash from submitted captcha number and compare with posted hash.
228     *
229     * @access  public
230     * @return  bool    True if number matches hash or false if EVIL ROBOT.
231     * @author  Quinn Comendant <quinn@strangecode.com>
232     * @since   07 Dec 2005 22:19:33
233     */
234    public function valid()
235    {
236        $number = getFormData('sc-captcha-input');
237        $hash = getFormData('sc-captcha-hash');
238
239        if ('' == $number . $hash) {
240            return false;
241        }
242
243        return $this->_getMD5key($number) == $hash;
244    }
245
246    /**
247     * Generate random number 3-to-5 digits long.
248     *
249     * @access  private
250     * @return  int         Generated number.
251     * @author  Quinn Comendant <quinn@strangecode.com>
252     * @since   07 Dec 2005 21:40:25
253     */
254    public function _getRandomNumber()
255    {
256        return mb_substr(strval(rand(10000, 99999)), 0, rand(3, 5));
257    }
258
259    /**
260     * Generate md5 hash of number using secret key.
261     *
262     * @access  private
263     * @param   string  $input  Input text to whack.
264     * @return  string  md5 sum of input + seed
265     * @author  Quinn Comendant <quinn@strangecode.com>
266     * @since   07 Dec 2005 21:53:35
267     */
268    public function _getMD5key($input)
269    {
270        return md5($this->secret_key . $input);
271    }
272
273}
274
Note: See TracBrowser for help on using the repository browser.