Index: common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.412
diff -u -r1.412 common.inc
--- common.inc	15 Dec 2004 21:16:53 -0000	1.412
+++ common.inc	24 Dec 2004 18:34:56 -0000
@@ -606,6 +606,27 @@
 
   return TRUE;
 }
+
+/**
+ * Validate captcha input by a user.
+ *
+ * Ensures that captcha answer matches the variable contents to prevent automated
+ * scripts from submitting a form.
+ *
+ * @param $data
+ *   The input to check.
+ * @return
+ *   TRUE if the input data matches the captcha session variable.
+ */
+function valid_captcha($data) {
+  if ($_SESSION['captcha_answer'] == '' || $_SESSION['captcha_answer'] != $data) return FALSE;
+
+  // clear captcha variable
+  unset($_SESSION['captcha_answer']);
+
+  return TRUE;
+}
+
 /**
  * @} End of "defgroup validation".
  */
@@ -1374,6 +1395,62 @@
   }
 
   return form_select($title, $name, $value, $weights, $description, $extra);
+}
+
+/**
+ * Format a captcha field.
+ *
+ * @return
+ *   A themed HTML string representing the field.
+ *
+ * The captcha field is always named 'captcha'. The required answer is saved
+ * to a session variable which is referenced in the valid_captcha() function.
+ */
+function form_captcha($description = '') {
+
+  $numbers = array(1 => t('one'), 2 => t('two'), 3 => t('three'), 4 => t('four'),
+    5 => t('five'), 6 => t('six'), 7 => t('seven'), 8 => t('eight'), 9 => t('nine'),
+    10 => t('ten'), 11 => t('eleven'), 12 => t('twelve'));
+
+  $operators = array(0 => array(name => t('plus'), symbol => '+'),
+    1 => array(name => t('minus'), symbol => '-'), 2 => array(name => t('multiplied by'), symbol => '*'),
+    3 => array(name => t('divided by'), symbol => '/'));
+
+  $operator = rand(0,count($operators)-1);
+
+  // choose numbers based on operator to keep the math simple
+  switch($operator) {
+    case 0:
+      // do addition logic
+      $firstNumber = rand(1,count($numbers)-1);
+      $secondNumber = rand(1,count($numbers)-1);
+      $_SESSION['captcha_answer'] = $firstNumber + $secondNumber;
+      break;
+    case 1:
+      // do subtraction logic
+      $firstNumber = rand(6,count($numbers)-1);
+      $secondNumber = rand(1,5);
+      $_SESSION['captcha_answer'] = $firstNumber - $secondNumber;
+      break;
+    case 2:
+      // do multiplication logic
+      $firstNumber = rand(1,8);
+      $secondNumber = rand(1,8);
+      $_SESSION['captcha_answer'] = $firstNumber * $secondNumber;
+      break;
+    case 3:
+      // do division logic
+      $secondNumber = rand(2,4);
+      $firstNumber = $secondNumber * rand(1,4);
+      $_SESSION['captcha_answer'] = $firstNumber / $secondNumber;
+      break;
+  }
+
+  $question = t('What is ') . $numbers[$firstNumber].' ' .
+                $operators[$operator]['name'].' '.$numbers[$secondNumber] . '?';
+  $description = ($description=='') ? t('This helps prevent automated submissions.') : $description;
+
+  return form_textfield($question, 'captcha', NULL, 15, 15, $description, NULL, TRUE);
 }
 
 /**
