simple text CAPTCHA

6:46 PM 10/22/2019

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a type of test / challenge to ensure that the response is given by a human, not machine.

Here, we try to implement a visual CAPTCHA and so an audio accompaniment is excluded. It should, but we'll we see this later on.

Type following random codes (challenge) into a textbox next to it. To get different code challenge, try click reload button.

CAPTCHA image challenge

Basic setup

index.php (this page)

		
<?php
	//start session
	session_start();
	
	//try recreate filename for captcha image (never pass on true session id).
	if(!isset($_SESSION['imgURL']))
		$_SESSION['imgURL'] = 'tmp/' . str_shuffle(session_id()) . '.png';
	$imgURL = $_SESSION['imgURL'];
	
	//if is checked then make note of it.
	if(!isset($_SESSION['chk']))
		$chk = 'Not checked yet';
	else{
		$chk = $_SESSION['chk'];
		unset($_SESSION['chk']);
	}
	
	//make new challenge, save to session
	$chrSet = '012345678abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	$chrSetLastIdx = strlen($chrSet) - 1;

	$txt = '';
	$txtLen = rand(4,8);

	for($i = 0; $i < $txtLen; $i++)
		$txt .= $chrSet[rand(0, $chrSetLastIdx)];
	$_SESSION['challenge'] = $txt;

	//print code txt challenge
	$fontFamily = 'courier-new.ttf';
	$fontSize = 18; //px
	$pad = 10; //px
	$angle = 0; //degree
	
	/*calc text bounding rectangle, with $pad included:
		$txtRect[0,1]: x & y of lower-left corner, 
		$txtRect[4,5]: x & y of upper-right corner.*/
	$txtRect = imagettfbbox($fontSize, 0, $fontFamily, $txt);
	$txtW = $txtRect[4] - $txtRect[0] + 2 * $pad;
	$txtH = $txtRect[1] - $txtRect[5] + 2 * $pad;
	
	$img = imagecreatetruecolor($txtW, $txtH);
	$imgBack = imagecolorallocate($img, 255, 255, 255);
	$imgFore = imagecolorallocate($img, 0, 0, 0);
	imagefilledrectangle($img, 0, 0, $txtW, $txtH, $imgBack);
	imagettftext($img, $fontSize, $angle, $pad, $txtH - $pad, $imgFore, $fontFamily, $txt);
	
	//make $imgBack transparent, save image to file, done with $img.
	imagecolortransparent($img, $imgBack);
	imagepng($img, $imgURL , 9);
	imagedestroy($img);
?>
<form method="post" action="check.php" autocomplete="off">
	<fieldset>
		<p>Type following random codes (challenge) into a textbox next to it. 
			To get different code challenge, try click reload button.</p>
		<img src="<?php echo $imgURL; ?>" alt="CAPTCHA image challenge">
		<input type="button" onclick="location.reload()" value="↻">
		<input type="text" name="captcha" value="">
		<button type="submit">Submit</button>
		<label><?php echo $chk; ?></label>
	</fieldset>
</form>

check.php

<?php
	//start session
	session_start();
	

	if($_SERVER['REQUEST_METHOD'] != 'POST')
		$_SESSION['chk'] = 'Invalid request';
	elseif(!isset($_POST["captcha"]) && !isset($_SESSION['challenge']))
		$_SESSION['chk'] = 'Invalid request';
	else{
		if($_POST["captcha"] == $_SESSION['challenge'])
			$_SESSION['chk'] = 'Matched, conrats!';
		else
			$_SESSION['chk'] = 'Not matched, sorry.';
	}
	session_write_close();
	header('Location: index.php');
	exit;
?>

Comments