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

Sample Perl Implementation

Perl Module

Have you read our HowTo?

Our perl sample is based on a module kindly published by Geoffrey Young on CPAN. To use it drop the file WebService/CaptchasDotNet.pm into a new subdirectory WebService in the directory containing the files using the module.

The original version don't use optional parameters alphabet, letters, width and height. If you want to upgrade, you have to uninstall the old 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 the required parameters
# 'demo' and 'secret' with the values you receive upon 
# registration at http://captchas.net.
#
# Optional Parameters and Defaults:
#
# alphabet: 'abcdefghijklmnopqrstuvwxyz' (Used characters in captcha)
# We recommend alphabet without ijl: 'abcdefghkmnopqrstuvwxyz'
#
# letters: '6' (Number of characters in captcha)
#
# width: '240' (image width)
# height: '80' (image height)
#
# Don't forget the same settings in check.cgi
#---------------------------------------------------------------------
my $captchas = WebService::CaptchasDotNet->new(
                                 client   => 'demo',
                                 secret   => 'secret'#,
                                 #alphabet => 'abcdefghkmnopqrstuvwxyz',
                                 #letters => 6,
                                 #width   => 240,
                                 #height  => 80,
                                 );
my $random     = $captchas->random;
my $image_url  = $captchas->image_url;
my $audio_url  = $captchas->audio_url;
my $image      = $captchas->image;

#---------------------------------------------------------------------
# Print html page
#---------------------------------------------------------------------
print "Content-Type: text/html\n\n";
print '<html>
<head>
  <title>Sample Perl CAPTCHA Query</title>
</head>
  <h1>Sample Perl CAPTCHA Query</h1>
  <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="16" />
        </td>
      </tr>
      <tr>
        <td>
        </td>
        <td>
          '
 . $image . '<a href="javascript:captchas_image_reload(\'captchas.net\')">Reload Image</a>
          <br> <a href="'
 . $audio_url . '">Phonetic spelling (mp3)</a>
          <br> <a href="'
 . $audio_url . '&language=de">Buchstabieren (mp3)</a>
          <br> <a href="'
 . $audio_url . '&language=it">Compitare (mp3)</a>
          <br> <a href="'
 . $audio_url . '&language=nl">Spellen (mp3)</a>
          <br> <a href="'
 . $audio_url . '&language=fr">Epeler (mp3)</a>
        </td>
      </tr>
      <tr>
        <td>
        </td>
        <td>
          <input type="submit" value="Submit" />
        </td>
      </tr>
    </table>
  </form>
</html>'
;
#---------------------------------------------------------------------
# End
#---------------------------------------------------------------------

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. Use same Settings as in query.cgi, 
# height and width aren't necessairy
#---------------------------------------------------------------------
my $captchas = WebService::CaptchasDotNet->new(
                                 client   => 'demo',
                                 secret   => 'secret'#,
                                 #alphabet => 'abcdefghkmnopqrstuvwxyz',
                                 #letters => 6
                                 );

#---------------------------------------------------------------------
# Validate and verify captcha password
#---------------------------------------------------------------------
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 the random string to be valid and return an error message
    # otherwise.
    if (not $captchas->validate ($random))
    {
      return 'Every CAPTCHA can only be used once. The current '
           . 'CAPTCHA has already been used. Try again.';
    }

    # Check that the right CAPTCHA password has been entered and
    # return an error message otherwise.
    # Attention: Only call verify if validate is true
    if (not $captchas->verify ($password))
    {
      return 'You entered the wrong password. '
           . 'Please use back button and reload.';
    }

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

#---------------------------------------------------------------------
# Print html page
#---------------------------------------------------------------------
print "Content-Type: text/html\n\n";
print '
<html>
  <head>
    <title>Sample Perl CAPTCHA Query</title>
  </head>
  <h1>Sample Perl CAPTCHA Query</h1>'
 .
    get_body () . '
</html>'
;
#---------------------------------------------------------------------
# End
#---------------------------------------------------------------------

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