Index: trunk/lib/Captcha.inc.php
===================================================================
--- trunk/lib/Captcha.inc.php	(revision 29)
+++ trunk/lib/Captcha.inc.php	(revision 29)
@@ -0,0 +1,201 @@
+<?php 
+/**
+ * Captcha.inc.php
+ * code by strangecode :: www.strangecode.com :: this document contains copyrighted information
+ *
+ * ASCII captcha system.
+ *
+ * @author  Quinn Comendant <quinn@strangecode.com>
+ * @version 1.0
+ */
+class Captcha {
+    
+    var $secret_key = 'some random seed text for the md5';
+    var $ascii_numbers = array(
+        array(
+            '  #####   ',
+            ' ##   ##  ',
+            '##     ## ',
+            '##     ## ',
+            '##     ## ',
+            ' ##   ##  ',
+            '  #####   ',
+        ), array(
+            '   ##   ',
+            ' ####   ',
+            '   ##   ',
+            '   ##   ',
+            '   ##   ',
+            '   ##   ',
+            ' ###### ',
+        ), array(
+            ' #######  ',
+            '##     ## ',
+            '       ## ',
+            ' #######  ',
+            '##        ',
+            '##        ',
+            '######### ',
+        ), array(
+            ' #######  ',
+            '##     ## ',
+            '       ## ',
+            ' #######  ',
+            '       ## ',
+            '##     ## ',
+            ' #######  ',
+        ), array(
+            '##        ',
+            '##    ##  ',
+            '##    ##  ',
+            '##    ##  ',
+            '######### ',
+            '      ##  ',
+            '      ##  ',
+        ), array(
+            '######## ',
+            '##       ',
+            '##       ',
+            '#######  ',
+            '      ## ',
+            '##    ## ',
+            ' ######  ',
+        ), array(
+            ' #######  ',
+            '##     ## ',
+            '##        ',
+            '########  ',
+            '##     ## ',
+            '##     ## ',
+            ' #######  ',
+        ), array(
+            '######## ',
+            '##    ## ',
+            '    ##   ',
+            '   ##    ',
+            '  ##     ',
+            '  ##     ',
+            '  ##     ',
+        ), array(
+            ' #######  ',
+            '##     ## ',
+            '##     ## ',
+            ' #######  ',
+            '##     ## ',
+            '##     ## ',
+            ' #######  ',
+        ), array(
+            ' #######  ',
+            '##     ## ',
+            '##     ## ',
+            ' ######## ',
+            '       ## ',
+            '##     ## ',
+            ' #######  ',
+        )
+    );
+    
+    /**
+     * Print ASCII number.
+     *
+     * @access  public
+     * @param   mixed   $num    Number to convert.
+     * @return  string  ASCII-ized number
+     * @author  Quinn Comendant <quinn@strangecode.com>
+     * @since   07 Dec 2005 21:59:25
+     */
+    function getAsciiNumber($num)
+    {
+        if (preg_match('/[^\d]/', $num)) {
+            App::logMsg(sprintf('Bad number: %s', $num), LOG_ERR, __FILE__, __LINE__);
+        	return false;
+        }
+        
+        // Number must be an array of strings.
+        $num = preg_split('// ', strval($num), -1, PREG_SPLIT_NO_EMPTY);
+
+        // All chars must be same height.
+        $output = '';
+        $char_height = sizeof($this->ascii_numbers[0]);
+        for ($i=0; $i<$char_height; $i++) {
+            foreach ($num as $n) {
+                $output .= $this->ascii_numbers[$n][$i];
+            }
+            $output .= "\n";
+        }
+        
+        return $output;
+    }
+    
+    /**
+     * Prints a form to enter captcha, including the required hidden hash form.
+     *
+     * @access  public
+     * @author  Quinn Comendant <quinn@strangecode.com>
+     * @since   07 Dec 2005 22:09:04
+     */
+    function printForm()
+    {
+        $number = $this->_getRandomNumber();
+        $hash = $this->_getMD5key($number);
+        $ascii = $this->getAsciiNumber($number);
+        ?>
+        <label for="sc-captcha"><?php echo _("Reverse Turing Test") ?></label>
+        <p class="help">Please enter the number here to prove you are a human. This is a measure to prevent spam robots from submitting this form.</p>
+        <pre style="font-size: 1px;"><?php echo $ascii ?></pre>
+        <input name="sc-captcha" id="sc-captcha" type="text" />
+        <input name="sc-captcha-hash" type="hidden" value="<?php echo $hash ?>" />
+        <?php
+    }
+    
+    /**
+     * Validate submitted number against ascii captcha. 
+     * Regenerate md5 hash from submitted captcha number and compare with posted hash.
+     *
+     * @access  public
+     * @return  bool    True if number matches hash or false if EVIL ROBOT.
+     * @author  Quinn Comendant <quinn@strangecode.com>
+     * @since   07 Dec 2005 22:19:33
+     */
+    function valid()
+    {
+        $number = getFormData('sc-captcha');
+        $hash = getFormData('sc-captcha-hash');
+
+        if ('' == $number . $hash) {
+        	return false;
+        }
+
+        return $this->_getMD5key($number) == $hash;
+    }
+
+    /**
+     * Generate random 4-digit number.
+     *
+     * @access  private
+     * @return  int         Number with 4 digits
+     * @author  Quinn Comendant <quinn@strangecode.com>
+     * @since   07 Dec 2005 21:40:25
+     */
+    function _getRandomNumber()
+    {
+        return rand(1000, 9999);
+    }
+        
+    /**
+     * Generate md5 hash of number using secret key.
+     *
+     * @access  private
+     * @param   string  $input  Input text to whack.
+     * @return  string  md5 sum of input + seed
+     * @author  Quinn Comendant <quinn@strangecode.com>
+     * @since   07 Dec 2005 21:53:35
+     */
+    function _getMD5key($input)
+    {
+        return md5($this->secret_key . $input);
+    }
+    
+}
+
+?>
