+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 10 of 18
Like Tree2Likes

Thread: [PHP Tut] Make your own CAPTCHA

  1. #1
    mattura's Avatar
    mattura is offline x10 Elder mattura is an unknown quantity at this point
    Join Date
    Oct 2007
    Posts
    563

    Post [PHP Tut] Make your own CAPTCHA

    I haven't seen a tutorial for this yet, so why not make one myself!

    First of all, you will need at least the intermediate version of x10's php, so upgrade your account if you haven't already.

    It also helps to have a reasonable knowledge of php (or you won't be able to customise this code!)

    What is a CAPTCHA?

    A CAPTCHA is a Completely Automated Public Turing test to tell Computers and Humans Apart. It gives you something that only a human can read, thereby helping to prevent spam. See here for more details: http://en.wikipedia.org/wiki/Captcha

    How do I make one?
    Simple! I'll take you through the steps. In the example I'll be creating a png, but it is possible to generate jpg, bmp etc as well.

    Step 1 - Create an empty image
    PHP Code:
    $imgheight=60;
    $imgwidth=400;  //whatever dimensions you need
    $img=imagecreatetruecolor($imgwidth,$imgheight);
    imagefill($img000x99ccff); //fill with light blue 
    For other background colours, change the '0x99ccff' to the hex value for your favourite colour.

    Step 2 - Generate random characters
    You may want to skip this step if you know how to get your random characters. There are many ways to do so, but one simple method follows:
    PHP Code:
    $str=substr(md5(uniqid(rand(), true)),0,6); //create random token of length 6 
    Step 3 - Make some random lines etc to confuse Optical Character Recognition
    Here we will be using the imageline function. Go look it up if you want to understand it.
    First, we will make an array of potential colour to choose from (we'll use this later for the letters as well). Choose them from here, but don't make any similar to the background colour.
    PHP Code:
    $colours=array(0x000055,0xff0000,0x009900,0xffcc99,0xff00ff,0x6b8e00);
    $cl=count($colours);  //makes processing faster 
    Then, using a loop to draw about 10 lines (you don't want to overcrowd things), pick random colour values from your array, and also random co-ordinates for each line. I complicated matters by using mostly horizontal-ish and vertical-ish lines, which are most likely to confuse an OCR. Don't worry too much if you don't understand, just copy and paste.
    PHP Code:
    for($i=0;$i<10;$i++) {
     
    $col=$colours[rand(0,$cl)]; //using your array of colour values
     
    $typ=rand(0,1); //draw either h/v line to confuse OCR
     
    if ($typ==1) { //horizontal line:
      
    $x1=rand(0,$imgwidth/2);$x2=rand($imgwidth/2,$imgwidth);
      
    $y1=rand(0,$imgheight);$y2=rand($y1-$imgheight/5,$y1+$imgheight/5);
     } else {   
    //vertical line:
      
    $x1=rand(0,$imgwidth);$x2=rand($x2-$imgwidth/5,$x2+$imgwidth/5);
      
    $y1=rand(0,$imgheight/2);$y2=rand($imgheight/2,$imgheight);
     }
     
    imageline($img,$x1,$y1,$x2,$y2,$col); //draw the actual line


    Step 4 - Write your letters on the image
    This makes use of the imagestring function. Again, go look it up if you want to understand it.
    PHP Code:
    $let=str_split($str); //convert your string to an array for convenience
    $strl=count($let); //count length for later
    foreach($let as $key=>$char) {
     
    $x=$imgwidth/2-$strl*8+$key*16;//*$siz*3+10+rand(1,5);
     
    $colour=$colours[rand(0,$cl)];
     
    imagestring($img,5,$x,$imgheight/2-6,$char,$colour);

    Step 5 - Outputting your image
    Ok, finally you are ready to send your image and see what you have produced.
    PHP Code:
    header("Content-type: image/png"); //send the appropriate header
    return imagepng($img); 
    That's it! Test your code now and enjoy the result!

    But wait - it's really quite small! This is because php's built-in font only has five sizes (1-5), which is what the '5' is in the imagestring line. It doesn't get any bigger!

    What can we do about it?
    Well, we can use a true type font.
    First, you need to find a nice font and save it in the same directory as your php file. If you use windows, you might find them in c:/windows/fonts. Make sure it is *.ttf

    Now instead of imagestring, use imagettftext.
    I used the following (with the Arial Black font ariblk.ttf saved in my web directory):
    PHP Code:
     $siz=16//font size, in pt
     
    $ang=0//angle of rotation - randomize this for even more fun!
     
    imagettftext($img$siz$ang$x$imgheight/2$colour"ariblk.ttf"$char); 
    You will have to change your $x and $y ($imgheight/2) values to reflect the font size

    Sample output, using above code:


    Sample output, using close together letters and angles between -10 and 20 (not too negative or 7 looks like 1):


    If additional distortion is required, you can use imagefilter to apply filters to your image after the letters have been written. The output below is generated by using the following code:

    PHP Code:
    imagefilter($img,IMG_FILTER_MEAN_REMOVAL); 
    Here's one with a different font (TempusITC.ttf). A little harder to read, but a lot harder to detect:


    Bear in mind
    The point is to make the image unreadable to a computer, not almost illegible for humans! Many people have great difficulty reading text which is a similar colour to the background, so try to make sure your colour array only contains light colours if your background is dark, or vice versa.
    If you eliminate the gap between letters (make them touch each other), clever OCR software has great difficulty in separating the individual letters, this is a huge problem for computers, yet is still pretty readable for humans. Do this if you are worried clever software will try to unleash spam on you. It's unlikely though!
    You should offer an alternative for accessibility purposes. Many sites offer an audible CAPTCHA.

    Have fun kiddies!
    Last edited by mattura; 05-30-2008 at 01:14 PM.
    ----
    Life is a game. The conception is terrible but the graphics are amazing!
    matt.elementfx.com

  2. #2
    marshian's Avatar
    marshian is offline x10 Elder marshian is an unknown quantity at this point
    Join Date
    Jan 2008
    Location
    Belgium
    Posts
    526

    Re: [PHP Tut] Make your own CAPTCHA

    If you're making a CAPTCHA, remember you have to know what the user has to enter!
    It's nice to have a good CAPTCHA, but if you can't verify the user's input, it's kinda useless ^^
    So remember you should store $str somewhere, preferably somewhere where the user can't access it. (No cookies or sessions and if you're using a file, remember you have to make sure the user can't find it.)

    You might want to take a look at http://libcaca.zoy.org/wiki/PWNtcha too, it shows a lot of crackable CAPTCHA's and there's some tips on makeing a good one I beleive...
    dinomirt96 likes this.
    Real programmers don't document their code - if it was hard to write, it should be hard to understand.

  3. #3
    mattura's Avatar
    mattura is offline x10 Elder mattura is an unknown quantity at this point
    Join Date
    Oct 2007
    Posts
    563

    Re: [PHP Tut] Make your own CAPTCHA

    Well of course you need to store the string.
    You can either use a session variable:
    PHP Code:
    $_SESSION['captcha']=$str;
    ---
    if (
    $_POST['user_entry']==$_SESSION['captcha']) {echo "Correct!";} 
    or you could include the file and use the $str value.
    Or just paste the above code in with your input form php file, and again, use the $str value direct.
    Don't use a cookie, as the user/spam-bot can read it! But session data is saved on the server, so it's safe.
    The tutorial was to create the captcha image, so I kinda didn't bother to write the whole form. You can do that yourself if you're looking into captchas!

    A good link above. Thanks

    I'd reiterate, that the hardest captchas to solve are those with characters joined up/overlapping
    Last edited by mattura; 05-30-2008 at 01:35 PM.
    ----
    Life is a game. The conception is terrible but the graphics are amazing!
    matt.elementfx.com

  4. #4
    DarkDragonLord's Avatar
    DarkDragonLord is offline x10 Elder DarkDragonLord is an unknown quantity at this point
    Join Date
    Mar 2007
    Location
    Brazil
    Posts
    782

    Re: [PHP Tut] Make your own CAPTCHA

    Great tutorial.

    I might try improve it in my Contact form (i still think isn't possible but ya, lets try...)

    +rep \o/










    btw: u might think, why his form cant? well, its ajax/php one, ajax check the things, then send to php, php process and give ok, ajax go and update div with OK (or error if have any)
    Last edited by DarkDragonLord; 05-30-2008 at 04:37 PM.
    Regards,
    Raphael DDL

    Designing Solutions for You
    *Web Design;
    *Coding;
    Free Downloads;
    and all related Stuff
    .


    My Tutorials:
    | Multi-Language Websites | Rotative Banners |
    | Bookmark Script for All Browsers
    |
    |
    PHP Switching/Including Content|
    |


  5. #5
    marshian's Avatar
    marshian is offline x10 Elder marshian is an unknown quantity at this point
    Join Date
    Jan 2008
    Location
    Belgium
    Posts
    526

    Re: [PHP Tut] Make your own CAPTCHA

    Quote Originally Posted by mattura View Post
    Well of course you need to store the string.
    You can either use a session variable:
    PHP Code:
    $_SESSION['captcha']=$str;
    ---
    if (
    $_POST['user_entry']==$_SESSION['captcha']) {echo "Correct!";} 
    or you could include the file and use the $str value.
    Or just paste the above code in with your input form php file, and again, use the $str value direct.
    Don't use a cookie, as the user/spam-bot can read it! But session data is saved on the server, so it's safe.
    The tutorial was to create the captcha image, so I kinda didn't bother to write the whole form. You can do that yourself if you're looking into captchas!

    A good link above. Thanks

    I'd reiterate, that the hardest captchas to solve are those with characters joined up/overlapping
    IMO, sessions aren't safe enough this way...
    http://www.webmasterworld.com/php/3371366.htm
    A malicious user could solve the CAPTCHA once, and then log in under that session, so he'ld just have to give in the same string every time...
    karimirt47 likes this.
    Real programmers don't document their code - if it was hard to write, it should be hard to understand.

  6. #6
    mattura's Avatar
    mattura is offline x10 Elder mattura is an unknown quantity at this point
    Join Date
    Oct 2007
    Posts
    563

    Re: [PHP Tut] Make your own CAPTCHA

    Session hijacking (http://en.wikipedia.org/wiki/Session_hijacking) is a different issue. If you have security concerns in this area, CAPTCHAs are the least of your worries!
    Even so, solving the CAPTCHA once does not mean it is solved the next time - every refresh will produce a different CAPTCHA and different $str. The user cannot access the $str themselves! All they have is the session id. Once solved, you can validate a post on a message board, or create a user account and be sure that it was a human that did so. A good standard security procedure for logins is to regenerate the session id against fixation attacks and session hijacking.
    Most of us will use a CAPTCHA just for creation of accounts, posting of items etc, in which case storing in $_SESSION is pretty safe.
    ----
    Life is a game. The conception is terrible but the graphics are amazing!
    matt.elementfx.com

  7. #7
    marshian's Avatar
    marshian is offline x10 Elder marshian is an unknown quantity at this point
    Join Date
    Jan 2008
    Location
    Belgium
    Posts
    526

    Re: [PHP Tut] Make your own CAPTCHA

    I think you don't get my point...
    For example you could have a page captcha.php, which shows a captcha and stores the $str under a certain session, and the form redirects to solvecaptcha.php, which checks wether you've given the right $str. A session-hijacker could go to captcha.php, see what the $str is and then hijack his current session so he can go to solvecaptcha.php without even having to see captcha.php (and that not once, but multiple times)
    Real programmers don't document their code - if it was hard to write, it should be hard to understand.

  8. #8
    mattura's Avatar
    mattura is offline x10 Elder mattura is an unknown quantity at this point
    Join Date
    Oct 2007
    Posts
    563

    Re: [PHP Tut] Make your own CAPTCHA

    No, I'm still not sure I get your point!
    A session-hijacker could go to captcha.php, see what the $str is
    They could see the CAPTCHA, but otherwise, they have no way of getting at the $_SESSION['str'] (it is never sent to the client). All they can find is the session id (which is some md5-type string, and IS sent to the client). They can hijack the session all they want, but only if they have seen the CAPTCHA with their eyes will they know what the string is.

    Granted, as you have pointed out, there is the possibility of multiple use for one CAPTCHA (in this example), so in this case it would be wise to destroy the $_SESSION['str'] after comparison (in solvecaptcha.php), so that the user could only use each captcha once.
    If that was your point, then I got it, but just assumed users (in the same session) would naturally be prevented from posting/creating accounts/whatever in quick succession. It's probably worth pointing out though, people don't think of everything...
    Last edited by mattura; 06-05-2008 at 06:19 PM.
    ----
    Life is a game. The conception is terrible but the graphics are amazing!
    matt.elementfx.com

  9. #9
    VPmase's Avatar
    VPmase is offline x10 Elder VPmase is an unknown quantity at this point
    Join Date
    Nov 2007
    Location
    Dixon, IL, USA
    Posts
    914

    Re: [PHP Tut] Make your own CAPTCHA

    I use AJAX for my captcha checks. Ofcourse this is because my entire registration form is AJAX. But still even if it wasn't, I'd still use AJAX. Allows for a much more lax captcha system while still keeping bots out.
    My system saves each captcha sting for an IP each time they go to the page. Lets say they end up straying from the page and the cap var changes but not the image, if they still have the old cap value it would still work xD

  10. #10
    mattura's Avatar
    mattura is offline x10 Elder mattura is an unknown quantity at this point
    Join Date
    Oct 2007
    Posts
    563

    Re: [PHP Tut] Make your own CAPTCHA

    Fair enough.
    Hopefully you have a graceful degradation for non-javascript users...
    The purpose of a CAPTCHA is to stop bots, so if you still get bots, you can find out why they are getting through, then upgrade/improve the CAPTCHA system. You'd have to have a pretty damn popular site to be targeted by aggressive bots, a simple captcha is good enough for most purposes.
    ----
    Life is a game. The conception is terrible but the graphics are amazing!
    matt.elementfx.com

+ Reply to Thread
Page 1 of 2 12 LastLast

Similar Threads

  1. [Game] Make Up A Definition
    By Starshine in forum Forum Games
    Replies: 115
    Last Post: 07-10-2011, 11:23 PM
  2. Your Website Needs
    By IamShipon1988 in forum Graphics & Webdesign
    Replies: 14
    Last Post: 06-21-2010, 07:47 AM
  3. Replies: 8
    Last Post: 06-19-2008, 09:46 PM
  4. Make $100 Per Week!
    By kesne in forum Earning Money
    Replies: 65
    Last Post: 06-08-2008, 01:31 PM
  5. How to make my sites address with register.com
    By unknownnasa1991 in forum Free Hosting
    Replies: 4
    Last Post: 05-01-2008, 06:12 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
x10hosting free hosting for the masses
dedicated servers