http://captchas.net http://captchas.net

Sample Perl Implementation

Perl Module

If you want to use the optional parameters alphabet, letters, width and height, please use our current version which is not published on CPAN yet.

Geoffrey Young has kindly provided a Perl module to simplify the task of writing a web application using captchas.net. It is named WebService::CaptchasDotNet. The latest version is always available at the above link at CPAN. If you do not want or cannot install the complete CPAN package, it is sufficient to drop the file CaptchasDotNet.pm into a new subdirectory WebService in the directory containing the files using the module.

Stages

Quering

In general the process of using CAPTCHA can be divided into two stages. First you have to query the user for the CAPTCHA, on that page you also usually let the user input the data, which has to be protected, e.g. blog entries.

The following script query.cgi implements this querying phase.

#!/usr/bin/perl

# Import the necessary module.
use WebService::CaptchasDotNet;

# Construct the captchas object. Replace 'demo' and 'secret' with
# the values you receive upon registration at http://captchas.net.
my $captchas = WebService::CaptchasDotNet->new(secret   => 'secret',
                                               username => 'demo');

# The website template.
my $template = 
    '<html><head><title>@TITLE@</title></head><h1>@TITLE@</h1>@BODY@</html>';


# Return the body of the webpage.
sub get_body {
    my $random = $captchas->random ();
    my $url = $captchas->url ($random);

    # Return the body table and with the random string and the
    # corresponding url.
    return '
        <form method="get" action="check.cgi">
          <table>
            <tr>
              <td>
                <input type="hidden" name="random" value="'
 . $random . '" />
                Your message:</td><td><input name="message" size="60" />
              </td>
            </tr>
            <tr>
              <td>
                The CAPTCHA password:
              </td>
              <td>
                <input name="password" size="6" />
              </td>
            </tr>
            <tr>
              <td>
              </td>
              <td>
                <a href="http://captchas.net">
                  <img style="border: none; vertical-align: bottom" 
                    src="'
 . $url . '" alt="The CAPTCHA image" />
                </a>
              </td>
            </tr>
            <tr>
              <td>
              </td>
              <td>
                <input type="submit" value="Submit" />
              </td>
            </tr>
          </table>
        </form>'
;
}

# Replace the title in the template
$template =~ s/\@TITLE\@/Sample Perl CAPTCHA Query/g;

# Replace the body in the template
my $body = get_body ();
$template =~ s/\@BODY\@/$body/;

# Output header according to CGI protocol.
print "Content-Type: text/html\n\n";

# Output the generated page.
print $template;

Checking

The second part is to check, whether the user has input the correct letter sequence (as given by the CAPTCHA image or audio). If that is the case the protected operation can be performed. Otherwise the corresponding error message is to be output.

There are two ways, in which a CAPTCHA check can fail. The user can have simply input the wrong letters. But also the random string can have been used more than once. If you would allow a random string to be used multiple times, a human could find out the correct CAPTCHA letter sequence for one random string once and use that information to make a robot post non-human entries to your web application, which still would seem made by a human.

The following script check.cgi implements this checking phase.

#!/usr/bin/perl

# Import the necessary modules.
use WebService::CaptchasDotNet;
use CGI;

# Construct the captchas object. Replace 'demo' and 'secret' with 
# the values you receive upon registration at http://captchas.net.
my $captchas = WebService::CaptchasDotNet->new(secret   => 'secret',
                                               username => 'demo');

# The website template.
my $template = 
    '<html><head><title>@TITLE@</title></head><h1>@TITLE@</h1>@BODY@</html>';


# Return the body of the webpage.
sub get_body {
    # Read the form values.
    my $query = new CGI;

    my $message = $query->param ('message');
    my $password = $query->param ('password');
    my $random = $query->param ('random');

    # Return an error message, when reading the form values fails.
    if (not (defined ($message) and defined ($password) and defined ($random)))
    {
        return 'Invalid arguments.';
    }

    # Check that the right CAPTCHA password has been entered and that
    # the random string to be valid and return an error message
    # otherwise.

    if (not $captchas->verify ($password, $random))
    {
        return 'Wrong Password entered or CAPTCHA used more than once. '
            . 'Try again.';
    }

    # Return a success message.
    return 'Your message was verified to be entered by a human and is "'
        . $message. '"';
}

# Replace the title in the template
$template =~ s/\@TITLE\@/Sample Perl CAPTCHA Query/g;

# Replace the body in the template
my $body = get_body ();
$template =~ s/\@BODY\@/$body/;

# Output header according to CGI protocol.
print "Content-Type: text/html\n\n";

# Output the generated page.
print $template;

Try it

You can also try the above scripts out yourself.

XHTML 1.1 compliant A service of Felix Holderied and Sebastian Wilhelmi (Contact) mail@captchas.net