From: Jamis Buck Date: 2004-10-26T00:35:23+09:00 Subject: Poor Man's CAPTCHA (was Re: Garden Spam) Austin Ziegler wrote: > On Mon, 25 Oct 2004 02:24:51 +0900, Jamis Buck wrote: > > >>I've got a PMC (poor man's captcha) that guards the comment submission >>for my blog (http://www.jamisbuck.org/jamis, and click a 'comment' link >>to see it). It's just plain text that must be entered backwards in a >>text box. Easily circumvented, 'tis true, but I haven't had a single >>spam comment on my blog since I implemented it. > > > Jamis, > > What did you use to do that captcha? That captcha I might actually > support using; I just don't want to do an image-based captcha because > of accessibility issues. > > -austin Just Ruby. In my blog-comments.rb file, I've got a method 'captcha' that returns the captcha block as HTML, expecting to be wrapped in a form: def captcha source = "23456789abdefghijkmnpqr" + "stuvwxyzABDEFGHJKLMNPQR" + "STUVWXYZ!?%\#@&*:\"<>".split(//) source = source.sort_by { rand } chars = (1..10).collect { source.shift } string = chars.join md5hash = MD5.hexdigest( string ) captcha_string = chars.reverse.collect { |i| "#{i} " }.join <<-EOF

Type the following characters in reverse order into the text box. Spaces are optional.

#{captcha_string}
What characters did you see: EOF end Then, when the form is submitted, I call 'validate_captcha': def validate_captcha checksum = @session['checksum'] captcha = @session['captcha'] sum = MD5.hexdigest( captcha.gsub(/\s/,"") ) sum == checksum end If this returns true, they entered the captcha string correctly. Like I said, it's pretty simple, and easily circumvented, but it's worked well for me so far. (The above code is in the public domain, so do with it as you will.) -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis