Thursday, May 25, 2006

Simple PHP encryption/decryption

Today Im going to show you some functions for simple encryption/decryption in PHP. Feel free to use any of this code. As always I am not responsible for any damage caused by the use or misuse of any of this code. And if you like my tutorial please visit and consider joining my website [Relaywrite.com].

See the functions in action here

The functions



  • Our first function is our encryption function called createsecretmessage. It takes two arguments, the message we want to encrypt and the key.

  • The second function is the decryption function. It also takes two arguements, the encrypted message and the key.


How does it work?


I'm glad you asked otherwise i would have nothing to say. The encryption function takes the ascii value of each character in the string and adds it an associated ascii value in the key. If the result is greater than 255(ascii maximum) it loops around by subtracting 256 from the combined value. The key is looped around as well so if we have a 5 character key then on character 6 of the message the function goes back to the first character of the key. The decryption function works pretty much the same but in reverse. It takes the encrypted message and subtracts from each character's ascii value the associated key ascii value. If the result is less than zero it adds 256 to compensate for the looping from the encryption function. Here is a picture of the encryption process.


encryption function



  • find length of string

  • find length of key

  • initiate a for loop to cylce through each character in the string

  • for each character get the ascii value of the message and the associated character from the key and add them together(use the modulous operater to get the remainder of the current character divided by the key length)
  • if the sum of the two values is less than or equal to 255, add that char value to our encrypted string

  • if the sum of the two values is greater than 255, subtract 256 then add that char value to our encrypted string

  • return our encrypted string



function createsecretmessage($message,$key)
{
$keylength = strlen($key);
$messagelength = strlen($message);
for($i=0;$i<=$messagelength - 1;$i++)
{
$msgord = ord(substr($message,$i,1));
$keyord = ord(substr($key,$i % $keylength,1));

if ($msgord + $keyord <= 255){$encstring .= chr($msgord + $keyord);}
if ($msgord + $keyord > 255){$encstring .= chr(($msgord + $keyord)-256);}
}
return $encstring;
}


decryption function



  • find length of string

  • find length of key

  • initiate a for loop to cylce through each character in the encrypted string

  • for each character get the ascii value of the message and the associated character from the key and subtract the key ascii value from the encrypted message ascii value(use the modulous operater to get the remainder of the current character divided by the key length)
  • if the difference of the two is greater than or equal to 0 then add that charachter value to our decrypted string

  • if the sum of the two values is less than 0, add 256 then add that char value to our decrypted string

  • return our decrypted string



function readsecretmessage($message,$key)
{
$keylength = strlen($key);
$messagelength = strlen($message);
for($i=0;$i<=$messagelength - 1;$i++)
{
$msgord = ord(substr($message,$i,1));
$keyord = ord(substr($key,$i % $keylength,1));

if ($msgord - $keyord >= 0){$decstring .= chr($msgord - $keyord);}
if ($msgord + $keyord < 0){$decstring .= chr(($msgord - $keyord)+256);}
}
return $decstring;
}


Copy and paste section...



function createsecretmessage($message,$key)
{
$keylength = strlen($key);
$messagelength = strlen($message);
for($i=0;$i<=$messagelength - 1;$i++)
{
$msgord = ord(substr($message,$i,1));
$keyord = ord(substr($key,$i % $keylength,1));

if ($msgord + $keyord <= 255){$encstring .= chr($msgord + $keyord);}
if ($msgord + $keyord > 255){$encstring .= chr(($msgord + $keyord)-256);}
}
return $encstring;
}

function readsecretmessage($message,$key)
{
$keylength = strlen($key);
$messagelength = strlen($message);
for($i=0;$i<=$messagelength - 1;$i++)
{
$msgord = ord(substr($message,$i,1));
$keyord = ord(substr($key,$i % $keylength,1));

if ($msgord - $keyord >= 0){$decstring .= chr($msgord - $keyord);}
if ($msgord + $keyord < 0){$decstring .= chr(($msgord - $keyord)+256);}
}
return $decstring;
}

echo "String to encrypt - ".$_POST[toenc]."

";
$encstring = createsecretmessage($_POST[toenc],$_POST[key]);
echo "encrypted string - " . $encstring ."

";
$decstring = readsecretmessage($encstring,$_POST[key]);
echo "decrypted string - " . $decstring ."

";



dont forget about my website


Relaywrite.com The collaborative writing project Relay Write

Tuesday, May 23, 2006

Easy PHP Captcha Tutorial

Easy PHP Captcha Tutorial



Today I'm going to show you how to quickly and easily write a captcha in PHP. You are free to use any of the code in your own work. All I ask is that you visit and consider joining the site that i wrote it for. [Relaywrite.com]


Here is a sample



The basic steps...



  • Create an image

  • Create random colors for background and text

  • Generate a random string of a random length

  • Generate a random angle for each character

  • Write characters to image

  • Put some random ellipses on the image some with the backround color and some with the text color

  • Save the string to a session variable for later verification

  • Output image to browser



Explanation...




Start PHP and start session session so that we can save our string into a session variable.



<?php
session_start();


Next we are going to generate a random number from 4 to 7 for our string length. After this we will use a for loop to assign a letter or number to each character in the string.

Note: I would generate a random number from 1 to 2 to decide if the character would be a letter or a number and then generate a random number from 48-57 for a number and assign the ASCII value of that to the character in the string and numbers from 65-90 for letters. But I started the numbers at 49 and excluded 79 to get rid of zero and O because they are too confusing.




$strlength = rand(4,7);

for($i=1;$i<=$strlength;$i++)
{
$textornumber = rand(1,3);
if($textornumber == 1)
{
$captchastr .= chr(rand(49,57));
}
if($textornumber == 2)
{
$captchastr .= chr(rand(65,78));
}
if($textornumber == 3)
{
$captchastr .= chr(rand(80,90));
}
}



Next we will generate some random RGB colors and initialize the image.




$randcolR = rand(100,230);
$randcolG = rand(100,230);
$randcolB = rand(100,230);

/initialize image $captcha is handle dimensions 200,50
$captcha = imageCreate(200,50);



Now we are going to set the colors for the image. The background colors will be the random RGB values that we just generated and we are going to make the text color a little lighter than the background color.

Note: the first color allocated is automatically used as the background color.



$backcolor = imageColorAllocate($captcha, $randcolR, $randcolG, $randcolB);

$txtcolor = imageColorAllocate($captcha, ($randcolR - 20), ($randcolG - 20), ($randcolB - 20));



And here is the heart of it all in this for loop. We set the for loop to iterate through each character. For each character we generate a random angle of rotation. We then use the php function imagettftext to place the characters in the image at the specified rotation at a random size from 14-20 pixels.


The syntax for the imagettftext function is:

array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text )



for($i=1;$i<=$strlength;$i++)
{

$clockorcounter = rand(1,2);
if ($clockorcounter == 1)
{
$rotangle = rand(0,45);
}
if ($clockorcounter == 2)
{
$rotangle = rand(315,360);
}

//$i*25 spaces the characters 25 pixels apart
imagettftext($captcha,rand(14,20),$rotangle,($i*25),30,$txtcolor,"/arial.ttf",substr($captchastr,($i-1),1));
}



The hard part is over and we are almost done. We are going to throw some ellipses on top of the image. Some with the background color some with the text color. The intended effect is to break up the image to make it harder for an ocr program to read. There is a trade off here. If you use too many shapes it is difficult for a human to read. If you use to few then it is easy for an automated script to crack.



for($i=1; $i<=4;$i++)
{
imageellipse($captcha,rand(1,200),rand(1,50),rand(50,100),rand(12,25),$txtcolor);
}
for($i=1; $i<=4;$i++)
{
imageellipse($captcha,rand(1,200),rand(1,50),rand(50,100),rand(12,25),$backcolor);
}



All we have left is to output the image to the browser and save the string in a session variable so that we can verify it later.



//Send the headers (at last possible time)
header('Content-type: image/png');

//Output the image as a PNG
imagePNG($captcha);

//Delete the image from memory
imageDestroy($captcha);

$_SESSION[captchastr] = $captchastr;

?>


Some things you might want to try



  • Make the text color and the background colors closer together

  • Add more ellipses or increase the width of the ellipses

  • Try some other shapes

  • Make the string longer

  • Increase rotation angles

  • Visit my website[Relaywrite.com]

Using the code


You will need to have arial.ttf in the same directory. On your php valitation form use the session variable we created and compare it with the user input for validation. To add the captcha to your for use the following code:




<img src='captcha.php'>


Now here is all the code



<?php
session_start();
$strlength = rand(4,7);

for($i=1;$i<=$strlength;$i++)
{
$textornumber = rand(1,3);
if($textornumber == 1)
{
$captchastr .= chr(rand(49,57));
}
if($textornumber == 2)
{
$captchastr .= chr(rand(65,78));
}
if($textornumber == 3)
{
$captchastr .= chr(rand(80,90));
}
}
$randcolR = rand(100,230);
$randcolG = rand(100,230);
$randcolB = rand(100,230);

/initialize image $captcha is handle dimensions 200,50
$captcha = imageCreate(200,50);
$backcolor = imageColorAllocate($captcha, $randcolR, $randcolG, $randcolB);

$txtcolor = imageColorAllocate($captcha, ($randcolR - 20), ($randcolG - 20), ($randcolB - 20));
for($i=1;$i<=$strlength;$i++)
{

$clockorcounter = rand(1,2);
if ($clockorcounter == 1)
{
$rotangle = rand(0,45);
}
if ($clockorcounter == 2)
{
$rotangle = rand(315,360);
}

//$i*25 spaces the characters 25 pixels apart
imagettftext($captcha,rand(14,20),$rotangle,($i*25),30,$txtcolor,"/arial.ttf",substr($captchastr,($i-1),1));
}
for($i=1; $i<=4;$i++)
{
imageellipse($captcha,rand(1,200),rand(1,50),rand(50,100),rand(12,25),$txtcolor);
}
for($i=1; $i<=4;$i++)
{
imageellipse($captcha,rand(1,200),rand(1,50),rand(50,100),rand(12,25),$backcolor);
}
//Send the headers (at last possible time)
header('Content-type: image/png');

//Output the image as a PNG
imagePNG($captcha);

//Delete the image from memory
imageDestroy($captcha);

$_SESSION[captchastr] = $captchastr;

?>

-Josh