PHP Image Distortion

In my article, PHP Image Code Verification, you may have noticed that it would be quite easy for a computer to read the code images, and enter the verification code automatically. In this article I will show you how to prevent this from happening by inserting random pixels to confuse the computers.

While this is not a 100% cheat proof concept, it can make it much more difficult to detect. If you are fighting comment spam, this could be the difference between 100 comments or 5. Chances are, if it will take a lot of CPU on their end to figure it out – they’ll go somewhere easier.

<?php
session_start();
session_register(‘sessioncode’);
$pixelnum = 20;
$width = 55;
$height = 15;
$im = imagecreate($width, $height);
$bg = imagecolorallocate($im, 255, 255, 255);
$textcolor = imagecolorallocate($im, 0, 0, 255);
imagecolortransparent($im, $bg);
imagestring($im, 5, 0, 0, substr(strtoupper(md5("Mytext".$sessioncode)), 0,6), $textcolor);
for ($j=0; $j<$pixelnum; $j++) {
$color = ImageColorAllocate($image, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($image, rand(0,$width), rand(0,$height), $color);
}
imagepng($im);
exit();
?>

First some minor changes in the previous code. I’ve added a width and height variable, and the imagecreate function now uses those variables. This is because the pixels also need the height and width, so putting them into variables will make it easier to change later.

I’ve also added a new variable, $pixelnum, this will be the number of pixels to insert into the image. The more pixels, the harder for users to read and the harder for computers to read.

The main section of code that has been added is this:

for ($j=0; $j<$pixelnum; $j++) {
$color = ImageColorAllocate($image, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($image, rand(0,$width), rand(0,$height), $color);
}

This code loops through the number of times to insert a pixel, picks a random color, and picks a random spot to insert a pixel. If your image doesn’t have any other color than the code text, you may want to change that code to this:

for ($j=0; $j<$pixelnum; $j++) {
imagesetpixel($image, rand(0,$width), rand(0,$height), $textcolor);
}

This will be harder for users to read, but computers wouldn’t be able to just ignore non blue colors and read it plainly. You could also try having a random color for the text itself, which would make it increasingly difficult. Just remember, if you over-due it, your users may be very frustrated trying to view the images.