不用session的图片验证码
作者:暖阳
[荐] 类别: PHP
用 session 实现图片验证码,浪费更多的服务器资源不说,对于客户端,也有一个弊病:如果开了一个新的窗口,因为session已更新,则在旧的窗口中按图片输入正确的字符串时,就变成错误的了.
前几天有人在 CSDN 里贴出一个双向加密的函数,顿时来了灵感,经过对这个函数进行改进,实现了不用session的图片验证码,在此与大家共享,望各位批评指正.
============= 文件: validate_image.php ================
<?php
/*
不用 session 实现的图片认证码 V1.0 sp2
作者: 暖阳
Email: faisun@sina.com
网站: http://www.softpure.com
转载请注明出处
*/
$validateCodeKeepTime = 60 * 5; //验证码有效时间,秒
function validateCode($string,$action="ENCODE"){ //字符串加密和解密
$secret_string = 'd0nf873498**&^%$JHJK'; //绝密字符串,可以任意设定
if($string=="") return "";
if($action=="ENCODE") $md5code=substr(md5($string),8,10);
else{
$md5code=substr($string,-10);
$string=substr($string,0,strlen($string)-10);
}
$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string);
$string = ($action=="ENCODE"?$string:base64_decode($string));
$len = strlen($key);
$code = "";
for($i=0; $i<strlen($string); $i++){
$k = $i%$len;
$code .= $string[$i]^$key[$k];
}
$code = ($action == "DECODE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code)."$md5code");
return $code;
}
function randString($len=4){ //产生随机字符串
$chars="23456789ABCDEFGHJKLMNPRSTWXY"; //验证码可取的字符,去掉不易辨认的字符
$string="";
for($i=0;$i<$len;$i++){
srand((double)microtime()*1000000);
$rand=rand(0,strlen($chars)-1);
$string.=substr($chars,$rand,1);
}
return strtoupper($string);
}
//输出图片
if($_REQUEST[action]=="getimage"){
$decode = validateCode($_GET["secretCode"],"DECODE");
list($string,$mytime)=split('@',$decode);
if(!$string||abs(time()-$mytime)>$validateCodeKeepTime) $string=' ';
Header("Content-type: image/gif");
$imageWidth = strlen($string)*20;
$imageHeight = 20;
$im = imagecreate($imageWidth,$imageHeight);
$backColor = ImageColorAllocate($im, rand(220,255),rand(220,255),rand(220,255)); //背景色
imagefilledrectangle($im, 0, 0, $imageWidth, $imageHeight, $backColor);
for($i=0;$i<100;$i++){ //画斑点
$dotColor = ImageColorAllocate($im, rand(0,255),rand(0,255),rand(0,255)); //点色
$x = rand(0,$imageWidth); $y = rand(0,$imageHeight);
imagesetpixel($im, $x, $y, $dotColor);
}
for($i=0;$i<strlen($string);$i++){ //写字
$frontColor = ImageColorAllocate($im, rand(0,120),rand(0,120),rand(0,120)); //字色
imagestring($im, 5, rand(20*$i+1,20*$i+10), rand(0,5), substr($string,$i,1),$frontColor);
}
imagepng($im);
imagedestroy($im);
exit;
}
?>
============ 应用举例,文件 demo.php =================
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>faisun@sina.com</title>
<style type="text/css">
body,td{ font-size:12px; }
</style>
</head>
<body>
<?
include("validate_image.php");
if($_REQUEST[action]=="confirm"){
list($mycode,$mytime)=split('@',validateCode($_POST["secretCode"],"DECODE"));
if(abs(time()-$mytime)>$validateCodeKeepTime){
echo "验证码已过期!";
exit;
}elseif(strlen($_POST["ValidateCode"])!=4||strtoupper($_POST[ValidateCode])!=$mycode){
echo "验证码错误!";
exit;
}else{
echo "验证码输入正确."; //改为你其他的处理代码.
}
}else{
?>
<form name="form1" method="post" action="">
<table width="300" border="0" cellspacing="0" cellpadding="3">
<tr>
<td width="110" align="right">验证码:</td>
<td width="178">
<?
$secretCode = validateCode(randString(4)."@".time());
?>
<input name="ValidateCode" type="text" id="ValidateCode" size="10" autocomplete="off">
<img src="validate_image.php?action=getimage&secretCode=<?=urlencode($secretCode);?>" align="absmiddle" id="validate_image"
onload="setTimeout("document.getElementById('validate_image').src='validate_image.php?action=getimage';",<?=$validateCodeKeepTime*1000; ?>);">
<input type='hidden' name='secretCode' value='<?=$secretCode;?>'>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><input name="action" type="hidden" id="action" value="confirm">
<input type="submit" name="Submit" value="确定"></td>
</tr>
</table>
</form>
<?
}
?>
</body>
</html>
前几天有人在 CSDN 里贴出一个双向加密的函数,顿时来了灵感,经过对这个函数进行改进,实现了不用session的图片验证码,在此与大家共享,望各位批评指正.
============= 文件: validate_image.php ================
<?php
/*
不用 session 实现的图片认证码 V1.0 sp2
作者: 暖阳
Email: faisun@sina.com
网站: http://www.softpure.com
转载请注明出处
*/
$validateCodeKeepTime = 60 * 5; //验证码有效时间,秒
function validateCode($string,$action="ENCODE"){ //字符串加密和解密
$secret_string = 'd0nf873498**&^%$JHJK'; //绝密字符串,可以任意设定
if($string=="") return "";
if($action=="ENCODE") $md5code=substr(md5($string),8,10);
else{
$md5code=substr($string,-10);
$string=substr($string,0,strlen($string)-10);
}
$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string);
$string = ($action=="ENCODE"?$string:base64_decode($string));
$len = strlen($key);
$code = "";
for($i=0; $i<strlen($string); $i++){
$k = $i%$len;
$code .= $string[$i]^$key[$k];
}
$code = ($action == "DECODE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code)."$md5code");
return $code;
}
function randString($len=4){ //产生随机字符串
$chars="23456789ABCDEFGHJKLMNPRSTWXY"; //验证码可取的字符,去掉不易辨认的字符
$string="";
for($i=0;$i<$len;$i++){
srand((double)microtime()*1000000);
$rand=rand(0,strlen($chars)-1);
$string.=substr($chars,$rand,1);
}
return strtoupper($string);
}
//输出图片
if($_REQUEST[action]=="getimage"){
$decode = validateCode($_GET["secretCode"],"DECODE");
list($string,$mytime)=split('@',$decode);
if(!$string||abs(time()-$mytime)>$validateCodeKeepTime) $string=' ';
Header("Content-type: image/gif");
$imageWidth = strlen($string)*20;
$imageHeight = 20;
$im = imagecreate($imageWidth,$imageHeight);
$backColor = ImageColorAllocate($im, rand(220,255),rand(220,255),rand(220,255)); //背景色
imagefilledrectangle($im, 0, 0, $imageWidth, $imageHeight, $backColor);
for($i=0;$i<100;$i++){ //画斑点
$dotColor = ImageColorAllocate($im, rand(0,255),rand(0,255),rand(0,255)); //点色
$x = rand(0,$imageWidth); $y = rand(0,$imageHeight);
imagesetpixel($im, $x, $y, $dotColor);
}
for($i=0;$i<strlen($string);$i++){ //写字
$frontColor = ImageColorAllocate($im, rand(0,120),rand(0,120),rand(0,120)); //字色
imagestring($im, 5, rand(20*$i+1,20*$i+10), rand(0,5), substr($string,$i,1),$frontColor);
}
imagepng($im);
imagedestroy($im);
exit;
}
?>
============ 应用举例,文件 demo.php =================
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>faisun@sina.com</title>
<style type="text/css">
body,td{ font-size:12px; }
</style>
</head>
<body>
<?
include("validate_image.php");
if($_REQUEST[action]=="confirm"){
list($mycode,$mytime)=split('@',validateCode($_POST["secretCode"],"DECODE"));
if(abs(time()-$mytime)>$validateCodeKeepTime){
echo "验证码已过期!";
exit;
}elseif(strlen($_POST["ValidateCode"])!=4||strtoupper($_POST[ValidateCode])!=$mycode){
echo "验证码错误!";
exit;
}else{
echo "验证码输入正确."; //改为你其他的处理代码.
}
}else{
?>
<form name="form1" method="post" action="">
<table width="300" border="0" cellspacing="0" cellpadding="3">
<tr>
<td width="110" align="right">验证码:</td>
<td width="178">
<?
$secretCode = validateCode(randString(4)."@".time());
?>
<input name="ValidateCode" type="text" id="ValidateCode" size="10" autocomplete="off">
<img src="validate_image.php?action=getimage&secretCode=<?=urlencode($secretCode);?>" align="absmiddle" id="validate_image"
onload="setTimeout("document.getElementById('validate_image').src='validate_image.php?action=getimage';",<?=$validateCodeKeepTime*1000; ?>);">
<input type='hidden' name='secretCode' value='<?=$secretCode;?>'>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td><input name="action" type="hidden" id="action" value="confirm">
<input type="submit" name="Submit" value="确定"></td>
</tr>
</table>
</form>
<?
}
?>
</body>
</html>
相关附件:
-= 资 源 教 程 =-
文 章 搜 索