source: tags/2.1.5/lib/Captcha.inc.php

Last change on this file was 377, checked in by quinn, 14 years ago

Releasing trunk as stable version 2.1.5

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-2010 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    var $secret_key = 'some random seed text for the md5';
57    var $random_number;
58    var $ascii_numbers = array(
59        array(
60            '  #####   ',
61            ' ##   ##  ',
62            '##     ## ',
63            '##     ## ',
64            '##     ## ',
65            ' ##   ##  ',
66            '  #####   ',
67        ), array(
68            '   ##   ',
69            ' ####   ',
70            '   ##   ',
71            '   ##   ',
72            '   ##   ',
73            '   ##   ',
74            ' ###### ',
75        ), array(
76            ' #######  ',
77            '##     ## ',
78            '       ## ',
79            ' #######  ',
80            '##        ',
81            '##        ',
82            '######### ',
83        ), array(
84            ' #######  ',
85            '##     ## ',
86            '       ## ',
87            ' #######  ',
88            '       ## ',
89            '##     ## ',
90            ' #######  ',
91        ), array(
92            '##        ',
93            '##    ##  ',
94            '##    ##  ',
95            '##    ##  ',
96            '######### ',
97            '      ##  ',
98            '      ##  ',
99        ), array(
100            '######## ',
101            '##       ',
102            '##       ',
103            '#######  ',
104            '      ## ',
105            '##    ## ',
106            ' ######  ',
107        ), array(
108            ' #######  ',
109            '##     ## ',
110            '##        ',
111            '########  ',
112            '##     ## ',
113            '##     ## ',
114            ' #######  ',
115        ), array(
116            '######## ',
117            '##    ## ',
118            '    ##   ',
119            '   ##    ',
120            '  ##     ',
121            '  ##     ',
122            '  ##     ',
123        ), array(
124            ' #######  ',
125            '##     ## ',
126            '##     ## ',
127            ' #######  ',
128            '##     ## ',
129            '##     ## ',
130            ' #######  ',
131        ), array(
132            ' #######  ',
133            '##     ## ',
134            '##     ## ',
135            ' ######## ',
136            '       ## ',
137            '##     ## ',
138            ' #######  ',
139        )
140    );
141   
142    /**
143     * Constructor. Initialized new random number.
144     *
145     * @access  public
146     * @author  Quinn Comendant <quinn@strangecode.com>
147     * @since   20 Jan 2006 13:08:22
148     */
149    function Captcha()
150    {
151        $app =& App::getInstance();
152   
153        $this->secret_key = $app->getParam('signing_key');
154        $this->random_number = $this->_getRandomNumber();
155    }
156
157    /**
158     * Print ASCII number.
159     *
160     * @access  public
161     * @param   mixed   $num    Number to convert.
162     * @return  string  ASCII-ized number
163     * @author  Quinn Comendant <quinn@strangecode.com>
164     * @since   07 Dec 2005 21:59:25
165     */
166    function getAsciiNumber($num=null)
167    {
168        $app =& App::getInstance();
169   
170        if (!isset($num)) {
171            $num = $this->random_number;
172        }
173
174        if (preg_match('/[^\d]/', $num)) {
175            $app->logMsg(sprintf('Bad number: %s', $num), LOG_ERR, __FILE__, __LINE__);
176            return false;
177        }
178
179        // Number must be an array of strings.
180        $num = preg_split('//', strval($num), -1, PREG_SPLIT_NO_EMPTY);
181
182        // All chars must be same height.
183        $output = '';
184        $char_height = sizeof($this->ascii_numbers[0]);
185        for ($i=0; $i<$char_height; $i++) {
186            foreach ($num as $n) {
187                $output .= $this->ascii_numbers[$n][$i];
188            }
189            $output .= "\n";
190        }
191
192        return $output;
193    }
194
195    /**
196     * Prints the captcha ASCII numbers.
197     *
198     * @access  public
199     * @author  Quinn Comendant <quinn@strangecode.com>
200     * @since   07 Dec 2005 22:09:04
201     */
202    function printAsciiNumber()
203    {
204        $ascii = $this->getAsciiNumber($this->random_number);
205        ?><pre id="sc-captcha"><?php echo $ascii ?></pre><?php
206    }
207
208    /**
209     * Prints a form to enter captcha, including the required hidden hash form.
210     *
211     * @access  public
212     * @author  Quinn Comendant <quinn@strangecode.com>
213     * @since   07 Dec 2005 22:09:04
214     */
215    function printForm()
216    {
217        $hash = $this->_getMD5key($this->random_number);
218        ?>
219        <input name="sc-captcha-input" id="sc-captcha-input" class="sc-small" type="text" />
220        <input name="sc-captcha-hash" id="sc-captcha-hash" type="hidden" value="<?php echo $hash ?>" />
221        <?php
222    }
223
224    /**
225     * Validate submitted number against ascii captcha.
226     * Regenerate md5 hash from submitted captcha number and compare with posted hash.
227     *
228     * @access  public
229     * @return  bool    True if number matches hash or false if EVIL ROBOT.
230     * @author  Quinn Comendant <quinn@strangecode.com>
231     * @since   07 Dec 2005 22:19:33
232     */
233    function valid()
234    {
235        $number = getFormData('sc-captcha-input');
236        $hash = getFormData('sc-captcha-hash');
237
238        if ('' == $number . $hash) {
239            return false;
240        }
241
242        return $this->_getMD5key($number) == $hash;
243    }
244
245    /**
246     * Generate random number 3-to-5 digits long.
247     *
248     * @access  private
249     * @return  int         Generated number.
250     * @author  Quinn Comendant <quinn@strangecode.com>
251     * @since   07 Dec 2005 21:40:25
252     */
253    function _getRandomNumber()
254    {
255        return mb_substr(strval(rand(10000, 99999)), 0, rand(3, 5));
256    }
257
258    /**
259     * Generate md5 hash of number using secret key.
260     *
261     * @access  private
262     * @param   string  $input  Input text to whack.
263     * @return  string  md5 sum of input + seed
264     * @author  Quinn Comendant <quinn@strangecode.com>
265     * @since   07 Dec 2005 21:53:35
266     */
267    function _getMD5key($input)
268    {
269        return md5($this->secret_key . $input);
270    }
271
272}
273
274?>
Note: See TracBrowser for help on using the repository browser.