source: trunk/lib/Captcha.inc.php @ 262

Last change on this file since 262 was 262, checked in by quinn, 17 years ago

Removed name="sc-captcha" from <pre> in Captcha.

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