Jump to content

PHP and CAPTCHAS.net


fireice87

Recommended Posts

Hey

 

Im looking into adding captcha to a registration form iv just used the sample from the captcha.net website to try it out and figure out how it works. Iv directly copied and pasted the code but its not quite working. Iv made no alterations to the code but keep getting the message 

 

"'Every CAPTCHA can only be used once. The current CAPTCHA has already been used. Try again.';"

 

as theres no forum on the captcha website im finding it hard to find what is causing this.

 

On the website (http://captchas.net/sample/php/) there is code for an input form and a cheack form along with the captcha function page below are copies of these

 

I figure as iv made no alterations this is probably some thing easy iv done wrong or a common mistake here is the section of code that triggers the message:

 

<?php
  // Check the random string to be valid and return an error message
  // otherwise.
  if (!$captchas->validate ($random_string))
  {
    echo '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.
  elseif (!$captchas->verify ($password))
  {
    echo 'You entered the wrong password. Aren\'t you human? Please use back button and reload.';
  }
  // Return a success message
  else
  {
    echo 'Your message was verified to be entered by a human and is "' . $message . '"';
  }
?>

 

 

 

The function:

<?php
//
// PHP module for easy utilization of the free captchas.net CAPTCHA service
//
// For documentation look at http://captchas.net/sample/php/
//
// Written by
//   Sebastian Wilhelmi <seppi@seppi.de> and
//   Felix Holderied <felix@holderied.de>
// This file is in the public domain.
//
// ChangeLog:
//
// 2006-08-16: New optional features integrated
//
// 2006-03-01: Only delete the random string from the repository in
//             case of a successful verification.
//
// 2006-02-14: Add new image() method returning an HTML/JavaScript
//             snippet providing a fault tolerant service.
//
// 2005-06-02: Initial version.
//

class CaptchasDotNet
{
  function CaptchasDotNet ($client, $secret,
                           $random_repository = '/strings/captchasnet-random-strings',
                           $cleanup_time      = 3600,
                           $alphabet          = 'abcdefghijklmnopqrstuvwxyz',
                           $letters           = 6,
                           $width             = 240,
                           $height            = 80
                           )
  {
    $this->__client = $client;
    $this->__secret = $secret;
    $this->__random_repository = $random_repository;
    $this->__cleanup_time      = $cleanup_time;
    $this->__time_stamp_file   = $random_repository . '/__time_stamp__';
    $this->__alphabet          = $alphabet;
    $this->__letters           = $letters;
    $this->__width             = $width;
    $this->__height            = $height;
  }

  function __random_string ()
  {
    // The random string shall consist of small letters, big letters
    // and digits.
    $letters = "abcdefghijklmnopqrstuvwxyz";
    $letters .= strtoupper ($letters) + "0123456789";

    // The random starts out empty, then 40 random possible characters
    // are appended.
    $random_string = '';
    for ($i = 0; $i < 40; $i++)
    {
      $random_string .= $letters{rand (0, strlen ($letters) - 1)};
    }

    // Return the random string.
    return $random_string;
  }

  // Create a new random string and register it.
  function random ()
  {
    // If the repository directory is does not yet exist, create it.
    if (!is_dir ($this->__random_repository))
    {
      mkdir ($this->__random_repository);
    }

    // If the time stamp file does not yet exist, create it.
    if (!is_file ($this->__time_stamp_file))
    {
      touch ($this->__time_stamp_file);
    }

    // Get the current time.
    $now = time ();

    // Determine the time, before which to remove random strings.
    $cleanup_time = $now - $this->__cleanup_time;

    // If the last cleanup is older than specified, cleanup the
    // directory.
    if (filemtime ($this->__time_stamp_file) < $cleanup_time)
    {
      $handle = opendir ($this->__random_repository);
      while (true)
      {
        $filename = readdir ($handle);
        if (!$filename)
        {
          break;
        }
        if ($filename != '.' && $filename != '..')
        {
          $filename = $this->__random_repository . '/' . $filename;
          if (filemtime ($filename) <  $cleanup_time)
          {
            unlink ($filename);
          }
        }
      }
      closedir ($handle);

      touch ($this->__time_stamp_file);
    }

    // loop until a valid random string has been found and registered,
    // but at most 20 times. If no valid random has been found during
    // that time, there is something really wrong. Also show the error
    // in the last run.
    for ($remaining = 20; $remaining > 0; $remaining--)
    {
      // generate a new random string.
      $random = $this->__random_string ();

      // open a file with the corresponding name in the repository
      // directory in such a way, that the creation fails, when the
      // file already exists. That should be near to impossible with
      // good seeding of the random number generator, but it's better
      // to play safe. If this is the last run, show the possible
      // error message.
      $filename = $this->__random_repository . '/' . $random;

      if ($remaining == 1)
      {
        $file = fopen ($filename, 'x');
      }
      else
      {
        $file = @fopen ($filename, 'x');
      }

      if ($file)
      {
        fclose ($file);
        break;
      }

      // if the file already existed, rerun the loop to try the next
      // string.
    }

    // return the successfully registered random string.
    $this->__random = $random;
    return $random;
  }

  //
  // Generates image-URL Parameters are only atached if different from default
  //
  function image_url ($random = False, $base = 'http://image.captchas.net/')
  {
    if (!$random)
    {
      $random = $this->__random;
    }
    $image_url  = $base;
    $image_url .= '?client='   . $this->__client;
    $image_url .= '&random='   . $random;
    if ($this->__alphabet!='abcdefghijklmnopqrstuvwxyz') {$image_url .= '&alphabet=' . $this->__alphabet;};
    if ($this->__letters!=6) {$image_url .= '&letters='  . $this->__letters;};
    if ($this->__width!=240) {$image_url .= '&width='    . $this->__width;};
    if ($this->__height!=80) {$image_url .= '&height='   . $this->__height;};
    return $image_url;
  }

  //
  // Same as image_url but without width and height
  //
  function audio_url ($random = False, $base = 'http://audio.captchas.net/')
  {
    if (!$random)
    {
      $random = $this->__random;
    }
    $audio_url  = $base;
    $audio_url .= '?client='   . $this->__client;
    $audio_url .= '&random='   . $random;
    if ($this->__alphabet!='abcdefghijklmnopqrstuvwxyz') {$audio_url .= '&alphabet=' . $this->__alphabet;};
    if ($this->__letters!=6) {$audio_url .= '&letters='  . $this->__letters;};
    return $audio_url;
  }

  //
  // Generates complete html-sample with javascript to reload image from
  // backup server
  //
  function image ($random = False, $id = 'captchas.net')
  {
    $image = <<<EOT
        <a href="http://captchas.net"><img
            style="border: none; vertical-align: bottom"
            id="@ID@" src="@URL@" width="@WIDTH@" height="@HEIGHT@"
            alt="The Captcha image" /></a>
        <script type="text/javascript">
          <!--
          function captchas_image_error (image)
          {
            if (!image.timeout) return true;
            image.src = image.src.replace (/^http:\/\/image\.captchas\.net/,
                                           'http://image.backup.captchas.net');
            return captchas_image_loaded (image);
          }

          function captchas_image_loaded (image)
          {
            if (!image.timeout) return true;
            window.clearTimeout (image.timeout);
            image.timeout = false;
            return true;
          }

          var image = document.getElementById ('@ID@');
          image.onerror = function() {return captchas_image_error (image);};
          image.onload = function() {return captchas_image_loaded (image);};
          image.timeout
            = window.setTimeout(
               "captchas_image_error (document.getElementById ('@ID@'))",
               10000);
          image.src = image.src;
          //-->
        </script>
EOT;
    $image = str_replace ('@HEIGHT@', $this->__height, $image);
    $image = str_replace ('@WIDTH@', $this->__width, $image);
    $image = str_replace ('@ID@', $id, $image);
    $image = str_replace ('@URL@', $this->image_url (), $image);
    return $image;
  }

  function validate ($random)
  {
    $this->__random = $random;

    $file_name = $this->__random_repository . '/' . $random;

    // Find out, whether the file exists
    $result = is_file ($file_name);

    // if the file exists, remember it.
    if ($result){
      $this->__random_file = $file_name;
    }

    // the random string was valid, if and only if the corresponding
    // file existed.
    return $result;
  }

  function verify ($input, $random = False)
  {
    if (!$random)
    {
      $random = $this->__random;
    }
    $password_letters = $this->__alphabet;
    $password_length  = $this->__letters;

    // If the user input has the wrong lenght, it can't be correct.
    if (strlen ($input) != $password_length)
    {
      return False;
    }

    // Calculate the MD5 digest of the concatenation of secret key and
    // random string. The digest is a hex string.
    $encryption_base = $this->__secret . $random;
    // This extension is needed for secure use of optional parameters
    // In case of standard use we do not append the values, to be
    // compatible to existing implementations
    if(($password_letters  != 'abcdefghijklmnopqrstuvwxyz') || ($password_length != '6'))
    {
      $encryption_base = $encryption_base . ':' . $password_letters  . ':' . $password_length;
    }
    $digest = md5 ($encryption_base);

    // Check the password according to the rules from the first
    // positions of the digest.
    for ($pos = 0; $pos < $password_length; $pos++)
    {
      $letter_num
        = hexdec (substr ($digest, 2 * $pos, 2)) % strlen ($password_letters);

      // If the letter at the current position is wrong, the user
      // input isn't correct.
      if ($input[$pos] != $password_letters[$letter_num])
      {
        return False;
      }
    }

    // if the file exists, remove it.
    if ($this->__random_file)
    {
      unlink ($this->__random_file);
      unset ($this->__random_file);
    }

    // The user input was correct.
    return True;
  }

}

?>

 

Input page:

<?php

require 'CaptchasDotNet.php';

// Required Parameters
// Replace the values you receive upon registration at http://captchas.net.
//
//   client: 'demo'
//
//   secret: 'secret'
//
// Optional Parameters and defaults
//
//   repository_prefix: '/tmp/captchasnet-random-strings' path to repository
//   ATTENTION SAFE-MODE, YOU HAVE TO CHOOSE SOMETHING LIKE
//   '/writable/path/captchasnet-random-strings'
//
//   cleanup_time: '3600' (means max 1 hour between query and check)
//
//   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)
//
//   Usage
//   $captchas = new CaptchasDotNet (<client>, <secret>,
//                                   <repository_prefix>, <cleanup_time>,
//                                   <alphabet>,<letters>,
//                                   <height>,<width>);
//
// Don't forget same settings in check.asp

// Construct the captchas object.

$captchas = new CaptchasDotNet ('demo', 'secret',
                                '/tmp/captchasnet-random-strings','3600',
                                'abcdefghkmnopqrstuvwxyz','6',
                                '240','80');

?>

<html>
  <head>
    <title>Sample PHP CAPTCHA Query</title>
  </head>
  <h1>Sample PHP CAPTCHA Query</h1>
  <form method="get" action="check.php">
    <table>
      <tr>
        <td>
          <input type="hidden" name="random" value="<?= $captchas->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>
          <?= $captchas->image () ?>
          <br> <a href="<?= $captchas->audio_url () ?>">Phonetic spelling (mp3)</a>
        </td>
      </tr>
      <tr>
        <td>
        </td>
        <td>
          <input type="submit" value="Submit" />
        </td>
      </tr>
    </table>
  </form>
</html>

Check page:

[code]<?php

require 'CaptchasDotNet.php';

// See query.php for documentation

$captchas = new CaptchasDotNet ('demo', 'secret',
                                '/tmp/captchasnet-random-strings','3600',
                                'abcdefghkmnopqrstuvwxyz','6',
                                '240','80');

// Read the form values
$message       = $_REQUEST['message'];
$password      = $_REQUEST['password'];
$random_string = $_REQUEST['random'];
?>

<html>
  <head>
    <title>Sample PHP CAPTCHA Query</title>
  </head>
  <h1>Sample PHP CAPTCHA Query</h1>

<?php
  // Check the random string to be valid and return an error message
  // otherwise.
  if (!$captchas->validate ($random_string))
  {
    echo '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.
  elseif (!$captchas->verify ($password))
  {
    echo 'You entered the wrong password. Aren\'t you human? Please use back button and reload.';
  }
  // Return a success message
  else
  {
    echo 'Your message was verified to be entered by a human and is "' . $message . '"';
  }
?>

</html>

[/code]

 

Thanks for looking and for any help  ;)

 

 

EDIT: well i mean i did make one alteration i changed the user name and password from demo and secret to my actual details

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.