You are here: Main 2007 11 24 Captcha.html

24-Nov: Ruby quick’n’dirty Captcha

As you probably know, this site you’re looking at right now relies on the Borg platform . Since Borg is still in its very early stage of development, I’m starting to address some of its current limitations. For example, user comments are still missing, but you cannot enable user comments without some sort of protection from spambots. Therefore, here come captchas .

The following snippet of code is a very simple solution to the problem. I use RMagick to generate an image which contains five random characters. To increase the difficulty of image recognition, I use a hatchfill background pattern and apply a little distortion to the generated image.

The sample code outputs the image to the standard output, since you’ll probably want to embed this code into a CGI-like interface, but it’s easy to modify it to write image files.

#!/usr/bin/env ruby
require 'rubygems'
require 'RMagick'

captcha = "" 
5.times { captcha << (rand(26)+65).chr }

canvas = Magick::Image.new(120,60, Magick::HatchFill.new('#ffffff','#4169e1'))

text = Magick::Draw.new
text.annotate(canvas,100,50,10,5,captcha) {
        self.fill = "#000000" 
        self.stroke = "transparent" 
        self.pointsize = 32
        self.font_weight = Magick::BoldWeight
        self.gravity = Magick::SouthGravity
}
canvas = canvas.implode(-0.4)
data = canvas.to_blob { self.format = "jpg" }
puts data

You can run the code from the command line in this way :

ruby captcha.rb > output.jpg

And you get an output similar to the one shown in the image. Clearly, a rather smart bot will still be able to read the captcha, but even this simple captcha is sufficient to fend off most of the attacks.

Last modified by: Riccardo Govoni [ battlehorse at gmail dot com ] at Mon Jan 28 01:06:09 -0500 2008