验证码是什么
验证码为全自动区分人和计算机的图灵测试的缩写,是一种区分用户是计算机或人的公共全自动程序。
验证码应用场景
- 登录、注册确定提交之前,做人/及其校验
- 发布、回复信息之前,做人/及其校验
- 疑似机器请求时,做人/及其校验
- …
验证码实现步骤
- 生成底图
- 生成验证内容
- 生成验证码图片
- 校验验证内容
所用到的PHP函数
imagecreatetruecolor ( int $width, int $height )
//创建一个宽$width高$height的画布
imagecolorallocate ( resource $image, int $red, int $green, int $blue )
//为画布分配颜色,red,green 和 blue分别是所需要的颜色的RGB值
imagefill ( resource $image, int $x, int $y, int $color )
//将分配好的颜色填充到画布
imagepng(resource $image [, string filename])
//输出一张png格式的图片
imagestring ( resource $image, int $fontsize, int $x, int $y, string $content, int $color )
//在画布上面水平写上文字
imagesetpixel ( resource $image, int $x, int $y, int $color )
//画一个点或者一个单一像素
imageline ( resource $image, int $x1, int $y1, int $x2, int $y2, int $color )
//画一条线段
substr ( string $string, int $start, int $length )
//详情请查看手册
imagedestroy ( $image )
//销毁图像资源,释放与 image 关联的内存
目标1
通过PHP代码,生成一张100*30px大小的图片
TIPS
- 依赖GD扩展
- 输出图片前必须提前输出图片header信息
- 该方法默认输出为黑色背景
<?php
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width,$height);
$pale = imagecolorallocate($image,204,204,204);
imagefill($image,0,0, $pale);
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
?>
目标2
在底图上显示随机数字
TIPS
注意好字体大小和分布,避免字体重叠或显示不全
<?php
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width,$height);
$pale = imagecolorallocate($image,204,204,204);
imagefill($image,0,0, $pale);
$length = 4;
for ($i=1;$i<=$length;$i++){
$fontsize = 6;
$fontcontent = mt_rand(0,9);
$x = $i*100/5;
$y = mt_rand(5,10);
$fontcolor = imagecolorallocate($image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
?>
目标3
为验证码增加干扰元素,干扰的点或线
TIPS
干扰信息一定要控制好颜色,避免喧宾夺主
<?php
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width, $height);
$bgcolor = imagecolorallocate($image,204,204,204);
imagefill($image,0,0,$bgcolor);
$length = 4;
for ($i=1;$i<=$length;$i++){
$fontsize = 6;
$x = $i*100/5;
$y = mt_rand(5,10);
$fontcontent = mt_rand(0,9);
$fontcolor = imagecolorallocate($image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
$pointnum = 200;
for ($i=1;$i<=200;$i++){
$x = mt_rand(1,99);
$y = mt_rand(1,29);
$pointcolor = imagecolorallocate($image,mt_rand(50,200),mt_rand(50,200),mt_rand(50,200));
imagesetpixel($image,$x,$y,$pointcolor);
}
$linenum = 3;
for ($i=1;$i<=$linenum;$i++){
$linecolor = imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,99),mt_rand(1,29),mt_rand(1,99),mt_rand(1,29),$linecolor);
}
header('content-type:image/png');
imagepng($image);
imagedestroy($iamge);
目标4
让图片上的验证码内容显示为字母或数字、字母的混合体
TIPS
N/A
<?php
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width, $height);
$bgcolor = imagecolorallocate($image,204,204,204);
imagefill($image,0,0,$bgcolor);
$length = 4;
for ($i=1;$i<=$length;$i++){
$fontsize = 6;
$x = $i*100/5;
$y = mt_rand(5,10);
$data = 'ABCDEFGHIGKMNOPQRSTUVWXYabcdefghijkmnopqrstuvwxy34567890';
$fontcontent = substr($data,mt_rand(0,strlen($data)),1);
$fontcolor = imagecolorallocate($image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
$pointnum = 200;
for ($i=1;$i<=200;$i++){
$x = mt_rand(1,99);
$y = mt_rand(1,29);
$pointcolor = imagecolorallocate($image,mt_rand(50,200),mt_rand(50,200),mt_rand(50,200));
imagesetpixel($image,$x,$y,$pointcolor);
}
$linenum = 3;
for ($i=1;$i<=$linenum;$i++){
$linecolor = imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,99),mt_rand(1,29),mt_rand(1,99),mt_rand(1,29),$linecolor);
}
ob_clean();
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
目标5
在服务器端记录验证码信息,便于用户输入后做校验
TIPS
- session_start()必须处于脚本最顶部
- 多服务器情况,需要考虑集中管理session信息
<?php
session_start();
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width, $height);
$bgcolor = imagecolorallocate($image,204,204,204);
imagefill($image,0,0,$bgcolor);
$length = 4;
$vertify_code = '';
for ($i=1;$i<=$length;$i++){
$fontsize = 6;
$x = $i*100/5;
$y = mt_rand(5,10);
$data = 'ABCDEFGHIGKMNOPQRSTUVWXYabcdefghijkmnopqrstuvwxy34567890';
$fontcontent = substr($data,mt_rand(0,strlen($data)),1);
$vertify_code .= $fontcontent;
$fontcolor = imagecolorallocate($image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
$_SESSION['authcode'] = $vertify_code;
$pointnum = 200;
for ($i=1;$i<=200;$i++){
$x = mt_rand(1,99);
$y = mt_rand(1,29);
$pointcolor = imagecolorallocate($image,mt_rand(50,200),mt_rand(50,200),mt_rand(50,200));
imagesetpixel($image,$x,$y,$pointcolor);
}
$linenum = 3;
for ($i=1;$i<=$linenum;$i++){
$linecolor = imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,99),mt_rand(1,29),mt_rand(1,99),mt_rand(1,29),$linecolor);
}
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
目标6
将已生成的验证码提供给用户,并校验用户验证码的正确性
TIPS
创建两个PHP文件:vertify.php和form.php
vertify.php文件代码
<?php
session_start();
$width = 100;
$height = 30;
$image = imagecreatetruecolor($width, $height);
$bgcolor = imagecolorallocate($image,204,204,204);
imagefill($image,0,0,$bgcolor);
$length = 4;
$vertify_code = '';
for ($i=1;$i<=$length;$i++){
$fontsize = 6;
$x = $i*100/5;
$y = mt_rand(5,10);
$data = 'ABCDEFGHIGKMNOPQRSTUVWXY34567890';
$fontcontent = substr($data,mt_rand(0,strlen($data)),1);
$vertify_code .= $fontcontent;
$fontcolor = imagecolorallocate($image,mt_rand(0,120),mt_rand(0,120),mt_rand(0,120));
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
$_SESSION['authcode'] = $vertify_code;
$pointnum = 200;
for ($i=1;$i<=200;$i++){
$x = mt_rand(1,99);
$y = mt_rand(1,29);
$pointcolor = imagecolorallocate($image,mt_rand(50,200),mt_rand(50,200),mt_rand(50,200));
imagesetpixel($image,$x,$y,$pointcolor);
}
$linenum = 3;
for ($i=1;$i<=$linenum;$i++){
$linecolor = imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,99),mt_rand(1,29),mt_rand(1,99),mt_rand(1,29),$linecolor);
}
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
form.php文件代码
<?php
header('content-type:text/html;charset=utf-8');
if (isset($_REQUEST['authcode'])){
session_start();
if (strtoupper($_REQUEST['authcode']) == $_SESSION['authcode']){
echo '输入正确';
}else{
echo '输入错误';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>确认验证码</title>
</head>
<body>
<form action="form.php" method="post">
<p>验证码图片: <img src="test.php" alt=""></p>
<p>请输入图片中的内容:<input type="text" name="authcode" value=""></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
目标7
验证码的动态校验及设计原理:“看不清、换一个”的实现原理
简单三步即可实现动态验证
- 增加可点击的“换一个”文案
- 用JS选取器选取验证码图片
- 用JS修改验证码图片地址(改src)
<?php
header('content-type:text/html;charset=utf-8');
if (isset($_REQUEST['authcode'])){
session_start();
if (strtoupper($_REQUEST['authcode']) == $_SESSION['authcode']){
echo '输入正确';
}else{
echo '输入错误';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>确认验证码</title>
</head>
<body>
<form action="form.php" method="post">
<p>验证码图片: <img id="vertify_img" src="vertify.php"></p>
<a href="javascript:void(0)" onclick="document.getElementById('vertify_img').src='vertify.php'">换一个?</a>
<p>请输入图片中的内容:<input type="text" name="authcode" value=""></p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
目标8
复杂验证码的实现:图片、视频验证码
图片、视频验证码实现方案类似
- 准备一定量的验证码物料库
- 做好物料的对应关系
发表评论