Dev (Back & Front)ARTIGO

Captcha em PHP com perguntas elaboradas

Captcha é um teste de desafio cognitivo
completamente automatizado para diferenciação entre computadores e
humanos. Um captcha usual envolve um computador (um servidor) que pede
que um usuário termine um teste. Como os computadores são incapazes de
resolver o captcha, todo usuário que incorpora uma solução correta é
presumidamente humano.

Completely Automated Public Turing test
to tell Computers and Humans Apart

Um tipo comum de captcha requer que o usuário identifique as letras
de uma imagem distorcida, às vezes com a adição de uma sequência
obscurecida das letras ou dos dígitos que apareça na tela.

Smartcaptcha

SmartCaptcha é um CAPTCHA desenvolvido por mim que,
diferente dos demais, formula as seguintes perguntas:

  • Quais letras são vogais?
  • Quais letras são consoantes?
  • Quais letras são “cor”?

As letras não são distorcidas, apenas inclinadas e coloridas.


Ver
imagem dinâmica gerada pelo SmartCaptcha

Como usar

Para criar um captcha com SmartCaptcha, você precisa instanciar a
classe e executar os métodos create e show.

$captcha = new SmartCaptcha;<br />$captcha->create();<br />$captcha->show();

Isso é quase o suficiente para você ter um captcha , um teste de
desafio cognitivo. Ainda falta armazenar o resultado para depois
compará-lo com o valor enviado pelo usuário, mesmo que esse usuário seja
um computador. Há duas formas simples de armazenar: por Sessão ou
Cookie.

Cada método tem sua singularidade. Sessão armazena os dados no
servidor e cria um cookie que servirá de elo para o próximo acesso.
Cookie
amazena os dados no computador do usuário, que são trafegados em
cada acesso/solicitação.

  • Por Sessão
$captcha = new SmartCaptcha;<br /><br />// inicia uma sessão<br />session_start();<br /><br />// grava a resolução do CAPTCHA na veriável de sessão "captcha"<br />$_SESSION['captcha'] = $captcha->create();<br /><br />$captcha->show();
  • Por Cookie
$captcha = new SmartCaptcha;<br /><br />// grava a resolução em um cookie de nome "captcha".<br />// tempo de vida desse cookie é de 30 minutos<br />setcookie('captcha', $captcha->create(), time() - 1800, '/', '.exemplo.com');<br /><br />$captcha->show();

Não importa qual método você escolha. No final das contas, o código
que receber as informações enviadas precisa rever a resposta do captcha que foi armazenada em sessão ou cookie, para usar como comparação com o
valor enviado e analisar se a resposta do usuário está correta, e então
dizer se ele é computador ou humano.

Atenção: se você tiver optado por cookie, saiba que cookies podem ser
facilmente lidos por softwares. Se o dado não for criptografado, há
grande chance de seu sistema ser burlado.

Exemplo de utilização

<?php<br /><br />// captcha-imagem.php<br /><br />session_start();<br /><br />$captcha = new SmartCaptcha;<br />$_SESSION['captcha'] = $captcha->create();<br />$captcha->show();<br /><br />?><br /><br /><!-- formulario.html --><br /><br /><form action="enviar.php" method="post"><br /><img src="captcha-imagem.php"/><br /><input type="text" name="captcha"/><br /><br />...<br /><br /><?php<br /><br />// enviar.php<br /><br />session_start();<br /><br />if ($_SESSION['captcha'] != $_POST['captcha']) {<br />	exit('Erro');<br />}<br /><br />?>

Personalizando seu CAPTCHA

O SmartCaptcha é personalizável. Você pode definir
fontes, cor de fundo, cores dos caracteres e quantidade de caracteres.

  • Fonte

O código usa a função imagettftext
do PHP para criar os caracteres. Essa função usa fontes TrueType.

As constantes SMARTCAPTCHA_FONT1 e SMARTCAPTCHA_FONT2
definem as fontes utilizadas pelo SmartCaptcha. Para
mudar a fonte do seu captcha, mude os valores dessas constantes.

define('SMARTCAPTCHA_FONT1', 'caminho/para/minha/fonte.tff');
  • Cor de fundo e dos
    caracteres

Cor de fundo e a cor dos caracteres são customizáveis. Cuidado, não
vá definir uma cor de fundo que dificulte a visualização dos caracteres, assim como não também não insira cores difíceis de serem identificadas. Muitas
pessoas não sabem a diferença entre azul celeste, azul turquesa e azul
marinho, inclusive eu.

$captcha = new SmartCaptcha;<br /><br /># branco, em RGB<br />$captcha->setBackgroundColor(255, 255, 255);<br /><br /># Ao definir uma cor, pense sempre na pergunta:<br /># Quais letras são ----?<br />$captcha->setColor('azuis celete', 50, 153, 204);<br />$captcha->setColor('corais', 255, 127, 0);<br />$captcha->setColor('violetas', 79, 47, 79);

Pode acontecer de uma cor que você tenha definido não apareça em
alguns CAPTCHAs. Não se esqueça de que as cores são escolhidas
aleatoriamente.

  • Quantidade de caracteres

O padrão do número de caracteres é cinco. Você pode aumentar ou diminuir
esse número.

$captcha = new SmartCaptcha;<br /><br /># CAPTCHA com 10 caracteres<br />$captcha->create(10);

Vale lembrar que uma quantidade grande de caracteres pode tornar a tarefa de responder
exaustiva e propícia a erros.

Código fonte

<?php<br />/**<br /> * SmartCaptcha<br /> *<br /> * @author Alejandro Fernandez Moraga <moraga86@gmail.com><br /> */<br /><br />define('SMARTCAPTCHA_FONT1', './Arial_Black.ttf');<br />define('SMARTCAPTCHA_FONT2', './Arial.ttf');<br /><br />class SmartCaptcha {<br /><br />	/**<br />	 * Imagem<br />	 *<br />	 * @var Resource<br />	 */<br />	private $image;<br /><br />	/**<br />	 * Cor de fundo do CAPTCHA<br />	 *<br />	 * @var Array<br />	 */<br />	private $backgroundColor = array(233, 234, 235);<br /><br />	/**<br />	 * Caracteres utilizados na composição do CAPTCHA<br />	 *<br />	 * @var Array<br />	 */<br />	private $chars = array(<br />		'vogais' => array('A', 'E', 'I', 'O', 'U'),<br />		'consoantes' => array('B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z')<br />	);<br /><br />	/**<br />	 * Cores utilizadas nos caracteres do CAPTCHA<br />	 *<br />	 * @var Array<br />	 */<br />	private $colors = array(<br />		'pretas' => array(0, 0, 0),<br />		'vermelhas' => array(255, 0, 0),<br />		'verdes' => array(0, 255, 0),<br />		'azuis' => array(0, 0, 255)<br />	);<br /><br />	/**<br />	 * Define a cor de fundo do CAPTCHA<br />	 *<br />	 * @param int $red Escala de vermelho<br />	 * @param int $green Escala de verde<br />	 * @param int $blue Escala de azul<br />	 * @return void<br />	 */<br />	function setBackgroundColor($red, $green, $blue) {<br />		$this->backgroundColor = array($red, $green, $blue);<br />	}<br /><br />	/**<br />	 * Define uma cor para os caracteres do CAPTCHA<br />	 *<br />	 * @param string $name Nome da cor no plural<br />	 * @param int $red Escala de vermelho<br />	 * @param int $green Escala de verde<br />	 * @param int $blue Escala de azul<br />	 * @return void<br />	 */<br />	function setColor($name, $red, $green, $blue) {<br />		$this->colors[$name] = array($red, $green, $blue);<br />	}<br /><br />	/**<br />	 * Remove uma cor das cores disponíveis para os caracteres do CAPTCHA<br />	 *<br />	 * @param string $name Nome da cor<br />	 * @return void<br />	 */<br />	function remColor($name) {<br />		unset($this->colors[$name]);<br />	}<br /><br />	/**<br />	 * Cria o CAPTCHA<br />	 *<br />	 * @param int $characteres Número de caracteres do CAPTCHA<br />	 * @return string Resposta do CAPTCHA<br />	 */<br />	function create($characters=5) {<br />		$pos_ini = 20;<br />		$chr_len = 35;<br /><br />		$charst = array_keys($this->chars);<br />		$colors = array_keys($this->colors);<br /><br />		# cria uma nova imagem<br />		$this->image = imagecreate($characters * $chr_len + $pos_ini * 2, 80);<br /><br />		# define a cor de fundo da imagem<br />		imagecolorallocate($this->image, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]);<br /><br />		# questões levantadas e suas respostas<br />		$avail = array();<br /><br />		for ($i=0; $i < $characters; $i++) {<br />			# escolhe um tipo de caractere entre vogal e consoante<br />			$chart = $charst[rand(0, 1)];<br /><br />			# escolhe um caractere do tipo previamente escolhido<br />			$c = $this->chars[$chart][rand(0, count($this->chars[$chart]) - 1)];<br /><br />			# habilita como resposta para tipos de caracteres<br />			if (empty($avail[$chart]))<br />				$avail[$chart] = $c;<br />			else<br />				$avail[$chart] .= $c;<br /><br />			# escolhe uma cor para o caractere<br />			$color = $colors[rand(0, count($this->colors) - 1)];<br /><br />			# habilita como respota para cores<br />			if (empty($avail[$color]))<br />				$avail[$color] = $c;<br />			else<br />				$avail[$color] .= $c;<br /><br />			# escreve o caractere na imagem<br />			imagettftext(<br />				# imagem<br />				$this->image,<br />				# largura<br />				30,<br />				# ângulo de inclinação<br />				rand(0, 25) * (rand(0, 1) ? 1 : -1),<br />				# posição no eixo x<br />				$chr_len * $i + $pos_ini,<br />				# posição no eixo y<br />				45,<br />				# cor do caractere<br />				imagecolorallocate($this->image, $this->colors[$color][0], $this->colors[$color][1], $this->colors[$color][2]), SMARTCAPTCHA_FONT1, $c);<br />		}<br /><br />		$questions = array_keys($avail);<br />		# escolhe uma pergunta<br />		$question = rand(0, count($avail) - 1);<br /><br />		# escreve a pergunta do CAPTCHA<br />		imagettftext($this->image, 10.5, 0, 5, 72, imagecolorallocate($this->image, 0, 0, 0), SMARTCAPTCHA_FONT2, 'Quais letras são '.$questions[$question].'?');<br /><br />		return $avail[$questions[$question]];<br />	}<br /><br />	/**<br />	 * Envia a imagem do CAPTCHA para o browser<br />	 *<br />	 * @return void<br />	 */<br />	function show() {<br />		header('Pragma: no-cache');<br />		header('Cache-Control: private, no-cache, no-cache="Set-Cookie", proxy-revalidate');<br />		header('Content-type: image/png');<br />		imagepng($this->image);<br />		imagedestroy($this->image);<br />	}<br />}<br /><br />?>

Código fonte destacado em: http://www2.jarbs.com.br/codes/SmartCaptcha/SmartCaptcha.phps

Download

Até a próxima!

é um cientista da computação. Atualmente é o webmaster da FAPESP. Já foi desenvolvedor de sistemas ERP e CRM na Internetmídia. Também desenvolve frameworks, ferramentas, sistemas e sites em nome da empresa METS, na qual é sócio junto com sua esposa, e é um pesquisador da Inteligência Artificial.

Ver perfil