PHP比较好的验证码.docx
《PHP比较好的验证码.docx》由会员分享,可在线阅读,更多相关《PHP比较好的验证码.docx(17页珍藏版)》请在冰豆网上搜索。
PHP比较好的验证码
php
/**
*VerificationCodeClass
*
*Usedtoanti-spambaseatPHPGDLib
*@authorEric,
*@version1.0
*@copyrightEreesoftInc.2009
*@update2009-05-1422:
32:
05
*@example
*session_sratr();
*$vcode=newVcode();
*$vcode->setLength(5);
*$_SESSION['vcode']=$vcode->paint();//TobeencryptedbyMD5
*/
classVcode{
/**
*@var$widthThewidthoftheimage,autoCalculated验证图片宽度,程序自动计算
*/
private$width;
/**
*@var$heightImageheight验证图片高度
*/
private$height;
/**
*@var$lengthVerificationCodelenght验证码长度
*/
private$length;
/**
*@var$bgColorImagebackgroundcolordefaultrandom验证图片背景色
*/
private$bgColor;
/**
*@var$fontColorThetextcolor验证码颜色
*/
private$fontColor;
/**
*@var$dotNoiseThenumberofnoise噪点数量
*/
private$dotNoise;
/**
*@var$lineNoiseThenumberofnoiselines干扰线数量
*/
private$lineNoise;
/**
*@var$imimageresourceGD图像操作资源
*/
private$im;
/**
*voidVcode:
:
Vcode()
*
*Theconstructor
*/
publicfunctionVcode(){
$this->dotNoise=20;//初始化噪点数量
$this->lineNoise=2;//初始化干扰线数量
}
/**
*voidVcode:
:
setLength(integer$length)
*
*SetVerificationCodelength
*@accesspublic
*@paraminteger$length;
*@returnvoid
*/
publicfunctionsetLength($length){
$this->length=$length;
}
/**
*voidVcode:
:
setBgColor(string$bgColor)
*
*SetbackgroundcoloroftheVerificationImage
*@accesspublic
*@paramstring$bgColore.g.:
#ffffff;可以直接使用css书写中的16进制写法,但不可简写
*@returnvoid
*/
publicfunctionsetBgColor($bgColor){
$this->bgColor=sscanf($bgColor,'#%2x%2x%2x');
}
/**
*voidVcode:
:
setFontColor(string$fontgColor)
*
*SettextcoloroftheVerificationImage
*@accesspublic
*@paramstring$fontColore.g.:
#ffffff;可以直接使用css书写中的16进制写法,但不可简写
*@returnvoid
*/
publicfunctionsetFontColor($fontColor){
$this->fontColor=sscanf($fontColor,'#%2x%2x%2x');
}
/**
*voidVcode:
:
setDotNoise(integer$num)
*
*Howmanynoisedotswanttodraw
*@accesspublic
*@paraminteger$numToomuchwilllowerperformance
*@returnvoid
*/
publicfunctionsetDotNoise($num){
$this->dotNoise=$num;//手动设置噪点数量后,会覆盖初始设置
}
/**
*voidVcode:
:
setLineNoise(integer$num)
*
*Howmanynoiselineswanttodraw
*@accesspublic
*@paraminteger$numToomuchwilllowerperformance
*@returnvoid
*/
publicfunctionsetLineNoise($num){
$this->lineNoise=$num;//手动设置干扰线数量后,会覆盖初始设置
}
/**
*StringVcode:
:
randString()
*
*CreateRandomcharacters生成随机字符串
*@accessprivate
*@returnString
*/
privatefunctionrandString(){
$string=strtoupper(md5(microtime().mt_rand(0,9)));
returnsubstr($string,0,$this->length);
}
/**
*voidVcode:
:
drawDot()
*
*Drawdotsnoise根据制定的数量随机画噪点,噪点颜色也随机
*@accessprivate
*/
privatefunctiondrawDot(){
for($i=0;$i<$this->dotNoise;$i++){
$color=imagecolorallocate($this->im,
mt_rand(0,255),
mt_rand(0,255),
mt_rand(0,255));//生成随机颜色
imagesetpixel($this->im,
mt_rand(0,$this->width),
mt_rand(0,$this->height),
$color);//在随机生成的坐标上画噪点
}
}
/**
*voidVcode:
:
drawLine()
*
*Drawlinenoise随机颜色随机画干扰线
*@accessprivate
*/
privatefunctiondrawLine(){
for($i=0;$i<$this->lineNoise;$i++){
$color=imagecolorallocate($this->im,
mt_rand(0,255),
mt_rand(0,255),
mt_rand(0,255));//随机生成颜色
imageline($this->im,
mt_rand(0,$this->width),
mt_rand(0,$this->height),
mt_rand(0,$this->width),
mt_rand(0,$this->height),
$color);//在随机生成的坐标上画干扰线
}
}
/**
*StringVcode:
:
paint()
*
*Createimageandoutput
*@accesspublic
*@returnstringTheVerificationCodetobeencryptedbyMD5
*/
publicfunctionpaint(){
if(empty($this->length))$this->length=4;//验证码默认长度为4
$this->width=$this->length*12+4;//计算验证图片宽度
$this->height=20;//制定验证码图片高度
$this->im=imagecreate($this->width,$this->height);//创建画布
if(empty($this->bgColor)||empty($this->fontColor)){//如果没有设置前景色和背景色则全部随机
//避免前景色和背景色过于接近,背景色(0-130)的随机范围与前景色(131-255)分开
imagecolorallocate($this->im,
mt_rand(0,130),
mt_rand(0,130),
mt_rand(0,130));
$randString=$this->randString();
for($i=0;$i<$this->length;$i++){
$fontColor=imagecolorallocate($this->im,
mt_rand(131,255),
mt_rand(131,255),
mt_rand(131,255));
imagestring($this->im,3,
$i*10+8,
mt_rand(0,8),
$randString{$i},
$fontColor);
//单个验证码字符高度随机,避免被OCR
}
}else{//如果设置了背景色和前景色,则不使用随机颜色
imagecolorallocate($this->im,
$this->bgColor[0],
$this->bgColor[1],
$this->bgColor[2]);
$randString=$this->randString();
$fontColor=imagecolorallocate($this->im,
$this->fontColor[0],
$this->fontColor[1],
$this->fontColor[2]);
for($i=0;$i<$this->length;$i++){
imagestring($this->im,3,
$i*10+8,
mt_rand(0,8),
$randString{$i},
$fontColor);//每个验证码字符高度仍然随机
}
}
$this->drawDot();//绘制噪点
$this->drawLine();//绘制干扰线
imagepng($this->im);
imagedestroy($this->im);
returnmd5($randString);//返回MD5加密后的验证码,可直接放入session
}
}
下面是调用方法
session_sratr();
$vcode=newVcode();
$vcode->setLength(5);
$_SESSION['vcode']=$vcode->paint();//TobeencryptedbyMD5
______________________________________________________________________________________________
首先我们建立一个login.html代码如下:
用户名:
|
密码:
|
验证码:
|
|
由以上代码我们可以看出我们必需建立两个PHP文件红色的PHP文件是我们要提交的目标文件也就验证提交信息是否合法的主要文件而蓝色的PHP文件则是我们的生成验证码的文件。
那么我们现在首先来看看code.php生成验证码的文件代码如下:
php
session_start();
$_SESSION['re_code']='';
$type='gif';
$width=38;
$height=15;
header("Content-type:
image/".$type);
srand((double)microtime()*1000000);
$randval=randStr(4,"ALL");
if($type!
='gif'&&function_exists('imagecreatetruecolor')){
$im=@imagecreatetruecolor($width,$height);
}else{
$im=@imagecreate($width,$height);
}
$r=Array(225,211,255,223);
$g=Array(225,236,237,215);
$b=Array(225,236,166,125);
$key=rand(0,3);
$backColor=ImageColorAllocate($im,$r[$key],$g[$key],$b[$key]);//背景色(随机)
$borderColor=ImageColorAllocate($im,20,66,111);//边框色
$pointColor=ImageColorAllocate($im,255,170,255);//点颜色
@imagefilledrectangle($im,0,0,$width-1,$height-1,$backColor);//背景位置
@imagerectangle($im,0,0,$width-1,$height-1,$borderColor);//边框位置
$stringColor=ImageColorAllocate($im,255,255,255);
for($i=0;$i<=100;$i++){
$pointX=rand(2,$width-2);
$pointY=rand(2,$height-2);
@imagesetpixel($im,$pointX,$pointY,$pointColor);
}
@imagestring($im,3,5,1,$randval,$stringColor);
$ImageFun='Image'.$type;
$ImageFun($im);
@ImageDestroy($im);
$_SESSION['re_code']=$randval;
//产生随机字符串
functionrandStr($len=6,$format='ALL'){
switch($format){
case'ALL':
$chars='ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';break;
case'CHAR':
$chars='ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz';break;
case'NUMBER':
$chars='123456789';break;
default:
$chars='ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
break;
}
$string="";
while(strlen($string)<$len)
$string.=substr($chars,(mt_rand()%strlen($chars)),1);
return$string;
}
?
>
以上代码保存成PHP文件即可生成gif的验证码图片,在生成图片的同时也将我们的生成的验证码保存到了$_SESSION['re_code']这个全局变量里所以我们在login.php这个文件里只需要判断用户填写的验证码是否与它相等就可以了。
(提示:
在login.php的最上方一定要先写session_start();才能使用$_SESSION['re_code'])写的很粗糙希望对看到此文的人有所帮助!
_______________________________________________________________________________________
代码一:
php
/*
*Filename:
authpage.php
*Author:
hutuworm
*Date:
2003-04-28
*@Copylefthutuworm.org
*/
srand((double)microtime()*1000000);
//验证用户输入是否和验证码一致
if(isset($HTTP_POST_VARS['authinput']))
{
if(strcmp($HTTP_POST_VARS['authnum'],$HTTP_POST_VARS['authinput'])==0)
echo"验证成功!
";
else
echo"验证失败!
";
}
//生成新的四位整数验证码
while(($authnum=rand()%10000)<1000);
?
>
请输入验证码:
80px">
echo$authnum;?
>>
authnum=
echo$authnum;?
>>
代码二:
php
/*
*Filename:
authimg.php
*Author:
hutuworm
*Date:
2003-04-28
*@Copylefthutuworm.org
*/
//生成验证码图片
Header("Content-type:
image/PNG");
srand((double)microtime()*1000000);
$im=imagecreate(58,28);
$black=ImageColorAllocate($im,0,0,0);
$white=ImageColorAllocate($im,255,255,255);
$gray=ImageColorAllocate($im,200,200,200);
imagefill($im,68,30,$gray);
//将四位整数验证码绘入图片
imagestring($im,5,10,8,$HTTP_GET_VARS['authnum'],$black);
for($i=0;$i<50;$i++)//加入干扰象素
{
imagesetpixel($im,rand()%70,rand()%30,$black);
}
ImagePNG($im);
ImageDestroy($im);
?
>
本文程序在Apache2.0.45+PHP4.3.1环境下运行通过。
上文只是对验证码功能的一个简单实现,并没有考虑商用安全性问题。
如果要增强安全性,将此功能投入商业应用,则可以通过以下几个步骤实现:
1.启用Session。
2.authnum在authimg.php中生成,并计算md5sum,存入session。
3.authpage.php将authinput计算md5sum后,与session中的authnum(md5sum)对比得出验证结果。
本站注:
作者使用了简单的代码实现了很酷的功能。
不过在添加干扰像素时的效果不是太好,大家可以看一下雨声论坛登录时的效验码(
修改后的代码如下:
php
/*
*Filename:
authimg.php
*Author:
hutuworm
*Date:
2003-04-28
*@Copylefthutuworm.org
*/
//生成验证码图片
Header("Content-type:
image/PNG");
srand((double)microtim