Preface

Capchas (completely automated public Turingtest to tell computers and humans apart) are a pain in the ass, but most of the time necessary.

Human faces images showing emotions are really hard to tell by nowadays software and extremly easy to identify for us.

So taking those two into consideration I've created this open source captcha software for all to use. Its main porpuse is to show an alternative to, now almost classic, text based captchas. Which sometimes are hard to tell and require more time that provably this approach.

As stated by Parrot (2010) there are 6 basic human emotions: love, joy, surprise, anger, sadness and fear. [categorization of emotions (wikipedia)] so these are the emotions that we can choose from in the select field.

To make things a little more complicated to computers this software also apply some filters to the image.

Example

Choose the emotion that the person in the picture is showing and press submit:

ruh capcha image

Requeriments

Ruh class (ruh.php)

This is the core of the application, Ruh class generates and prepares the image to be shown as well as checking for the correctness of the answer.

<?php

/************************/
/* ruh (aRe yoU Human?) */
/************************/
/* GPL/MIT license      */
/* vespre.com/ruh        */
/************************/

class Ruh {
    public 
$imgId '';
    public 
$type NULL;
    public 
$types = array('love''joy''surprise''anger''sadness''fear');

    private function 
generate() {
        
$this->imgId uniqid();
        
$this->type $this->types[array_rand($this->types1)];
        
        
$this->saveToSession();
    }
    
    private function 
saveToSession() {
        
// IF YOU USE A SESSION OTHER THAN PHP CHANGE IN HERE :
        
$_SESSION['ruh'][$this->imgId] = $this->type;
    }
    
    private function 
getFromSession() {
        
// IF YOU USE A SESSION OTHER THAN PHP CHANGE IN HERE :
        
$this->type $_SESSION['ruh'][$this->imgId];
        
//unset($_SESSION['ruh'][$this->imgId]);
    
}

    private function 
haveSession() {
        
// IF YOU USE A SESSION OTHER THAN PHP CHANGE IN HERE :
        
if (session_id() == '') {
            return 
false;
        } else {
            return 
true;
        }
    }
    
    public function 
getTypes() {
        return 
$this->types;
    }
    
    public function 
checkAnswer($answer) {
        if ((
$this->imgId != '') && ($this->type != NULL) && ($this->type == $answer)) {
            return 
true;
        } else {
            return 
false;
        }
    }
    
    public function 
generateImg() {
        
$imgList $this->getImgList();

        
// we get a random image from the choosen emotion
        
$image imagecreatefrompng('./' $this->type '/' $imgList[array_rand($imgList1)]);

        
// apply some filters
        
$filters =  array(IMG_FILTER_NEGATEIMG_FILTER_GRAYSCALEIMG_FILTER_EDGEDETECTIMG_FILTER_EMBOSSIMG_FILTER_GAUSSIAN_BLURIMG_FILTER_SELECTIVE_BLUR);
        
imageFilter($image$filters[array_rand($filters1)]);
        
        
imagepng($image);
        
imagedestroy($image);
    }

    private function 
getImgList() {
        
$imgList = array();
        
$dir './' $this->type;
        if (
is_dir($dir)) {
            if (
$dh opendir($dir)) {
                while ((
$file readdir($dh)) !== false) {
                    if (
filetype($dir '/' $file) == 'file') {
                        
$imgList [] = $file;
                    }
                }
                
closedir($dh);
                return(
$imgList);
            }
        }
    }
    
    public function 
getImgId() {
        return 
$this->imgId;
    }
    
    function 
__construct($imgId false) {
        if (!
$this->haveSession()) {
            throw new 
RuntimeException('No session was initialized');
        }

        if (
$imgId !== false) {
            
$this->imgId $imgId;
            
$this->getFromSession();
        } else {
            
$this->generate();
        }
    }
}

img.php

This simple script outputs the generated image.

<?php
header
('Content-Type: image/png');
// we need to start SESSION
session_start();

// we need to include the ruh class/library (require for generating a fatal error in case it fails)
require_once('./ruh.php');

$ruh = new Ruh($_GET['imgId']);

$ruh->generateImg();

.htaccess

Here the important part is the second line; which states that all png petitions will be handled by the img.php script, where the "name" of the images will be the imgId

RewriteEngine on
RewriteRule (.*).png img.php?imgId=$1 [L]

DirectoryIndex index.php

example.php

Here you have a very simple example of how to use it.

<?php
// As we use php $_SESSION to handle the persistance
// we need to start it: 
session_start();
// in case you use another session system you will need
// to look deeper into ruh.php and change the necessary.

// we need to include the ruh class/library (require for generating a fatal error)
require_once('./ruh.php');

// bypass any cache: (not stricly necessary)
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
?>
<html>
 <head>
    <title>ruh example.php (aRe yoU Human?) capcha using human emotions (GPL in php)</title>
 </head>
 <body>
    <h1>aRe yoU Human? Captcha example.php</h1>

<?php
    
if (isset($_POST['_submit_check'])) {
        
// Form was submited
        // create a new Ruh Object based on ImgId
        
$responseRuh = new Ruh($_POST['imgId']);
        
        
// check if the answear is correct
        
if ($responseRuh->checkAnswer($_POST['emotion']))
            echo 
'<h2 style="color: green">Correct!</h2>' PHP_EOL;
        else
            echo 
'<h2 style="color: red">Wrong!</h2>' PHP_EOL;
    }
?>

    <form method="POST" id="ruhForm" name="ruhForm" action="<?php echo $_SERVER['PHP_SELF']; ?>">

<?php
    
// we create a new Ruh Object:
    
$ruh = new Ruh(); // no params for the constructor as it is a new one.
?>
        <img src="<? echo $ruh->getImgId(); ?>.png" alt="ruh capcha image" />

        <input type="hidden" name="imgId" id="imgId" value="<? echo $ruh->getImgId(); ?>"/>
        <input type="hidden" name="_submit_check" value="1" /> <!-- to check for form submit -->

        <select id="emotion" name="emotion">
            <option value="joy">joy</option>
            <option value="surprise">surprise</option>
            <option value="love">love</option>
            <option value="anger">anger</option>
            <option value="sadness">sadness</option>
            <option value="fear">fear</option>
        </select>
        <input type="submit">
    </form>
 </body>
</html>

Acknowledge

Some of the images where taken from http://www.cs.unc.edu/~andrei/expressions/ and some more where from google images, if you plan to use this application remove these images and find your own, as these images may be preproceced by a potentian attacker and ruin all the system.