From: Ruby Quiz Date: 2005-09-23T21:38:31+09:00 Subject: [QUIZ] Math Captcha (#48) The three rules of Ruby Quiz: 1. Please do not post any solutions or spoiler discussion for this quiz until 48 hours have passed from the time on this message. 2. Support Ruby Quiz by submitting ideas as often as you can: http://www.rubyquiz.com/ 3. Enjoy! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= by Gavin Kistner Overview -------- "What is fifty times 'a', if 'a' is three?" #=> 150 Write a Captcha system that uses english-based math questions to distinguish humans from bots. Background and Details ---------------------- A 'captcha' is an automated way for a computer (usually a web server) to try to weed out bots, which don't have the 'intelligence' to answer a question that's fairly straightforward for a human. Captcha is an acronym for "Completely Automated Public Turing-test to tell Computers and Humans Apart" The most common form of captcha is an image that has been munged in such a way that it's supposed to be very hard for a computer to tell you what it says, but easy for a human. Recent studies (or at least articles) claim that it's proven quite possible to write OCR software that determines the right answer a large percentage of the time. Although image-based captchas can be improved (for example, by placing multiple colored words and asking the user to identify the 'cinnamon' word), they still have the fatal flaw of being inaccessible to the visually impaired. This quiz is to write a different kind of captcha system - one that asks the user questions in plain text. The trick is to use mathematics questions with a variety of forms and varying numbers, so that it should be difficult (though of course not impossible) to write a bot to parse them. For example, this questions of this form might be easy for a bot to parse: "What is five plus two?" while this question should be substantially harder: "How much is fifteen-hundred twenty-three, less the amount of non-thumbs on one human hand?" A good balance between human comprehension, variety of question form, and ease of computation is an interesting challenge. The Rules --------- Write a module that has two module methods: 'create_question' and 'check_answer'. The create_question method should return a hash with two specific keys: p MathCaptcha.create_question #=> { :question => "Here is the string of the question", :answer_id => 17 } The check_answer method is passed a hash with two specific keys, and should return true if the supplied answer is correct, false if not. p MathCaptcha.check_answer :answer => "Answer String", :answer_id => 17 #=> false Extra Credit ------------ 1) Ensure that your library is easily extensible, making it easy for someone using your library to add new forms of question creation, and the answer that goes with each form. 2) For automated testing and non-ruby usage, it would be nice to provide your module with a command-line wrapper, with the following interface: > ruby math_captcha.rb 1424039 : What is the sum of the number of thumbs on a human and the number of hooves on a horse? > ruby math_captcha.rb --id 1424039 --answer 7 false > ruby math_captcha.rb --id 1424039 --answer 6 true 3) Allow your 'create_question' method to take an integer difficulty argument. Low difficulties (0 being the lowest) represent trivial questions that an elementary school student might be able to answer, while higher difficulties range into algebra, trigonometry, calculus, linear algebra, and beyond. (It's up to you as to what the scale is.) "Type the number that comes right before seventy-five." "What is fifteen plus twelve minus six?" "What is six x minus three i, if I said that i is two and x three?" "What is two squared, cubed?" "Is the cosine of zero one or zero?" "What trigonometric function of an angle of a right triangle yields the ratio of the adjacent side's length divided by the hypotenuse?" "What is the derivative of 2x^2, when x is 3?" "What is the dot product of the vectors [4 7] and [3 4]?" "What is the cross product of the vectors [4 7] and [3 4]?" 4) Let your 'check_answer' method take a unique identifier (such as an IP address) along with the answer, and always return false for that identifier after a certain number of consecutive (or accumulated) failures have occurred. A Tip - Generating English Numerals ----------------------------------- Presumably parsing large numbers from english to computerese adds another stumbling block for any bot writer. ("5 + 2" is slightly easier than "five plus two" and a fair amount easier than "three-thousand-'n'-five twenty three plus five-oh-five". Ruby Quiz #25 has some nice code that you can appropriate for turning integers into english: http://www.rubyquiz.com/quiz25.html