///Anti-Automated Registration

Anti-Automated Registration

Anti-Automated Registration

Have you ever seen popular sites that block automated registrations with an image that has some garbled string? These are extremely hard for a computer to read, but they are extremely easy to generate.

The only things you need are GD (to create the images), a nice font (it’s got to look good, no?), and a couple minutes of time to read and follow along with this tutorial.

This is going to require a session. Don’t worry if you’ve never used them before, you’ll hardly even notice their presence. In the beginning of the file, we just need to session_start(); to tell it to start the session. This session is only going to hold one variable: what the image says. We obviously need to keep track of this so we can check whether or not the user has entered the correct string (and, thus, is a human).

We now need a form, something to get the input from the user. It also needs to display the image, of course. If you want to do this all in one page, keep in mind that you will need to output either the form or the image, never both at the same time. You can do this by setting a GET variable when you want to display the image: file.php?showimage=true. Somewhere in the form file, you need to set a session variable for the word on the image. Make sure this isn’t output to the user, or the entire script is ruined. One can set a session variable by using $_SESSION["variable"] = "value";. Of course, you’re going to want to use a more random string, but a static one will do for now. Here’s what I am using: $_SESSION["crc"] = chr(rand(0,25)+97). chr(rand(0,25)+97). chr(rand(0,25)+97). rand(0,9). rand(0,9). rand(0,9);

Now we can start to generate the image. I like to use TrueType Fonts (TTF), but you can feel free to use whatever type you want–GD has several different accepted font types. To get the size of the image we’re going to create, we need to use a bounding box, imagettfbbox() is what I’ll be using.

Now that we have dimensions for the image, let’s garble it up a bit. A bunch of random polygons will do the trick. I will be using this complex algorithm:

  for ($x=0; $x<15; $x++) {
    for ($y=0; $y<7; $y++) {
    $color = imagecolorclosest($im, rand(100,255), rand(100,255), rand(100,255));
    $points = array(
     rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
     rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
     rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
     rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y)
    );
    imagefilledpolygon($im,$points,3,$color);
   }
  }

After the polygon background has been drawn, go ahead and put the text on the image. Remember to use the same settings you used in the bounding box, or it won’t fit in the image right. Tweek your settings on the bounding box and the text so you can get it to look how you want.

You’re almost done. All you need to do is check if the value that was sent in by the user (from the previously created form) matches the session value. This is a very simple if: if ($_POST["word"] == $_SESSION["crc"]) { }

You’re done! Here’s a copy of my file in case you have any trouble with the tutorial:

session_start();
if (isset($_POST["word"])) {
  if (strtolower($_SESSION["crc"]) == strtolower($_POST["word"])) {
    echo("Matched!");
  }
  else {
    echo("Didn’t match.");
  }
}
else {
  $self = $_SERVER[‘PHP_SELF’];
  if ($_GET["im"] == TRUE) {
    $mycrc = $_SESSION["crc"];
    header("Content-type: image/png");
    $size = imagettfbbox(30, 3, "../Fonts/georgia.ttf", $mycrc);
    $im = imagecreatetruecolor(abs($size[4]-$size[0]), (abs($size[5])+$size[1]));
    $white = imagecolorallocate($im, 255, 255, 255);
    imagefill($im, 0, 0, $white);
    $black = imagecolorallocate($im, 0, 0, 0);
    for ($x=0;$x<15;$x++) {
      for ($y=0;$y<7;$y++) {
        $color = imagecolorclosest($im, rand(100,255), rand(100,255), rand(100,255));
        $points = array(
          rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
          rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
          rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y),
          rand(-5,5)+rand(5*$x,10*$x), rand(-5,5)+rand(5*$y,10*$y)
        );
        imagefilledpolygon($im, $points, 3, $color);
      }
    }
    imagettftext($im, 27, 4, 5, 33, $black, "../Fonts/georgia.ttf", $mycrc);
    imagepng($im);
    exit();
  }
  $_SESSION["crc"] = chr(rand(0,25)+97) . chr(rand(0,25)+97) . chr(rand(0,25)+97) . rand(0,9) . rand(0,9) . rand(0,9);
  echo <<<END
<img src="$self?im=1" alt="Please type this word."><br />
<form method="post" action="$self">
Please type the above word:<br />
<input type="text" name="word" value=""><br />
<input type="submit" name="submit" value="Submit Query">
</form>
END;
}
2010-05-26T09:46:16+00:00 June 23rd, 2005|PHP|0 Comments

About the Author:

Brandon is a young web developer who puts emphasis in new web standards
and all the best practices.  Working mostly in open source projects of
his own, he has come to a great understanding with PHP, and helps others
to reach an understanding of their own.

Over the years as a web developer and software tinkerer, he has learned
new ways to overcome previously impossible tasks and still learns with
every large project.  He considers the web a constantly changing
environment, and has adapted to fit it.

Leave A Comment