随即中文验证码
动态校验
实现字母和数字混合验证码
for 循环,字典由字母与数字组成。
imagesetpixel画一个随机的像素。
imagesetpixel(resource $iamge,int $x,int $y,int color)
imageline(resource $image,int $x1,int $y1,int $x2,int $y2,int $color)画一条线端。
实现数字验证码
在底图上显示随机数字
for循环
变色验证码
随机的点——干扰元素
实现数字验证码
在底图上显示随机数字
for循环
变色验证码
随机的点——干扰元素
搭建php运行环境,搜索XAMPP下载安装。
打开xampp文件地址,在站点文件夹htdots下,新建一个php文件。输入简单的内容判断是否能正常运行。
检查php是否支持GD,输入<?php phpinfo():查看输出即可。
实现简单的验证码
在htdots站点下,打开project目录创建php文件;
生成底图:图像绘制imagecreatetruecolor(int $width,int $height) 。
header方法输出图片的类型;
imagecreatetruecolor(int $width,int $height) 。默认返回黑色底图。
imagecolorallocate($image,int red,int green,int blue)为图像分配颜色。
9.imagefill($image,int x,int y,int color)区域填充,在iamge图像的坐标x,y(图像左上角为(0,0)处用color颜色执行区域填充;
<?php
//phpinfo();
//生成验证码底图
$image=@imagecreatetruecolor(100, 30);//返回一个黑色的图片
$text_color = imagecolorallocate($image, 255, 255, 255);
// $bgcolor=imagecolorallocate($image,255,255,255);
// imagefill($image,0,0,$bgcolor);
// header('content-type: image/png');
// imagedestroy($image);
imagefill($image,0,0,$text_color);//区域填充
for($i=0;$i<4;$i++)//利用for循环生成四位数字
{
$fontsize=6;//字体大小
$fontcolor=imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));//设置数字的颜色
$fontcontent=rand(0,9);
//注意事项:控制好字体的大小和分布,避免字体重叠或显示不全
$x=($i*100/4)+rand(5,10);
$y=rand(5,10);
imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}
for($i=0;$i<200;$i++)
{
$pointcolor=imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));
//生成随机点干扰颜色(较浅),给恶意破解程序增加难度
imagesetpixel($image,rand(1,99),rand(1,99),$pointcolor);
}
header ('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
<?php
//phpinfo();
//生成验证码底图
$image=@imagecreatetruecolor(120, 20);//返回一个黑色的图片
$text_color = imagecolorallocate($image, 255, 255, 255);
// $bgcolor=imagecolorallocate($image,255,255,255);
// imagefill($image,0,0,$bgcolor);
// header('content-type: image/png');
// imagedestroy($image);
imagefill($image,0,0,$text_color);//区域填充
header ('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
文字无法显示
输出一个随机数。 有的浏览器会对相同url做cache,若cache了,这个请求就达不到我们效果。所以加个随机数,避免被浏览器cache。
有的浏览器不够聪明,会cache历史数据,导致刷新失败。 加随机数是这个作用。
http://www.imooc.com/qadetail/25142
https://bbs.csdn.net/topics/390932524
这表示你的程序前面有输出,<?php 前有空格、空行、文件有BOM头
SESSION 存储验证信息
实现简单的验证码
captcha.php
<?php
session_start();
//画布
$image = imagecreatetruecolor(100, 30);
$bgcolor = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $bgcolor);
//随机数字
/*
for ($i=0; $i < 4; $i++) {
$fontsize = 10;
$fontcolor = imagecolorallocate($image, rand(0,120), rand(0,120), rand(0,120));
$fontcontent = rand(0,9);
$x = ($i*100/4) + rand(5,10);
$y = rand(5,10);
imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor);
}
*/
$captch_code = '';
//数字字母组合
for ($i=0; $i <4; $i++) {
$fontsize = 8;
$fontcolor = imagecolorallocate($image, rand(0,80), rand(0,80), rand(0,80));
$data = 'abcdefghijkmnpqrstuvwxy3456789';
$fontcontent = substr($data, rand(0,strlen($data)),1);
$captch_code .= $fontcontent;
$x = ($i*100/4) + rand(5,10);
$y = rand(5,10);
imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor);
}
$_SESSION['authcode'] = $captch_code;
//将captch_code保存到session的authcode中
//干扰点
for ($i=0; $i <300 ; $i++) {
$pointcolor = imagecolorallocate($image, rand(80,220), rand(80,220), rand(80,220));
imagesetpixel($image, rand(1,99), rand(1,29), $pointcolor);
}
//干扰线
for ($i=0; $i <3 ; $i++) {
$linecolor = imagecolorallocate($image, rand(120,220), rand(120,220), rand(120,220));
imageline($image, rand(1,99), rand(1,29), rand(1,99), rand(1,29), $linecolor);
# code...
}
header('content-type: image/png');
imagepng( $image );
//end
imagedestroy( $image );
?>
form.php
<?php
header('content-type:text/html;charset=utf-8');
if(isset($_REQUEST['authcode'])){
session_start();
if(strtolower($_REQUEST['authcode'])==$_SESSION['authcode']){
echo '<font color="#0000CC">输入正确</font>';
}else{
echo '<font color="#CC0000"> <b>输入错误</b> </font>';
}
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>确认验证码</title>
</head>
<body>
<form method="post" action="./form.php">
<p>验证码图片:<img id="captcha_img" border="1" src="./captcha.php?r=<?php echo rand();?>" width:100px; height:30px" />
<a href="javascript:void(0)" onclick="document.getElementById('captcha_img').src='./captcha.php?r='+Math.random()">换一个?</a>
<p>请输入图片中的内容:<input type="text" name="authcode" value="" /></p>
<p><input type="submit" value="提交" ></p>
</form>
</body>
</html>
“写请求的消耗远大于读请求”
<?php
session_start();
$captcha_code='';
for($i=0;$i<4;$i++){
$data='abcdefghigkmnpqrstuvwxy13456789';
$fontcontent=substr($data,rand(0,strlen($data)-1),1);
$captcha_code.=$fontcontent;
}
$_SESSION['authcode']=$captcha_code;
echo $_SESSION['authcode'];
//证明session是开着的
/* $str = '1';
$str .= '2';
$str .= '3';
$str .='4';
echo $str; 拼接规则的实验*/
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>确认验证码</title>
</head>
<?php
if(isset($_REQUEST['authcode'])){
session_start();
if(strtolower($_REQUEST['authcode'])==$_SESSION['authcode']){
echo '<font color="#0000CC">输入正确</font>';
}else{
echo '<font color="#CC0000"><b>输入错误<b></font>';
}
exit();
}
?>
<!--php代码还是放在head和body之间方便-->
<!--基本没啥好说的这几个表单直接替换“captcha.php”这些关键位置就可以了,另外就是画布的长宽
另外这里:document.getElementById('captcha_cn').src='./captcha_cn.php?r='+Math.random()的拼接规则注意一下-->
<body>
<form method="post" action="./form.php">
验证码图片:<img id="captcha_cn" src="./captcha_cn.php?r=<?php echo rand();?>" width=200 height=60>
<a href="javascript:void(0)" onclick="document.getElementById('captcha_cn').src='./captcha_cn.php?r='+Math.random()">换一个?</a>
<p>请输入图片内容:<input type="text" name="authcode" value="" placeholder="请输入图片中的内容"/></p>
<p><input type="submit" value="提交" style="padding:6px 20px;"></p>
</form>
</body>
</html>
<?php
session_start();
$table=array(
'pic0'=>'鸟',
'pic1'=>'猫',
'pic2'=>'狗',
'pic3'=>'鱼'
) ;
$index=mt_rand(0,3);
$value=$table['pic'.$index];
$_SESSION['authcode']=$value;
//$filename=dirname(__FILE__).'\\pic'.$index.'jpg';
$filename=dirname(__FILE__).'\\pic'.$index.'.jpg';//__FILE__这里两条下划线不要忘了,相邻的两个“.”差点搞死我
$contents=file_get_contents($filename);
//header('content-type:image/jpg');//输出内容前??
echo $contents;
//end
imagedestroy();
无字典版
<?php
session_start();
$image =imagecreatetruecolor(200,60);
$bgcolor=imagecolorallocate($image,255,255,255);//#ffffff
imagefill($image,0,0,$bgcolor);
$fontface='simfang.ttf';//这里我用仿宋
$strdb=array('慕','课','网','赞');
//1.画数字(字典)
$captcha_code='';
for($i=0;$i<4;$i++){
$fontcolor = imagecolorallocate($image, mt_rand(0,120), mt_rand(0,120), mt_rand(0,120));
$cn=$strdb[$i];
$captcha_code.=$cn;
imagettftext($image,mt_rand(20,24),mt_rand(-60,60),($i*50+10),mt_rand(35,40),$fontcolor,$fontface,$cn);
}//错误:这里之前少了一个参数“字体大小”;字体大小是20-24,所以i=0的时候X的值太小的话有可能没边,要考虑到。
$_SESSION['authcode']=$captcha_code;
//2.画干扰点
for($i=0;$i<200;$i++){
$pointcolor=imagecolorallocate($image,mt_rand(50,200),mt_rand(50,100),mt_rand(50,200));
imagesetpixel($image,mt_rand(1,199),mt_rand(1,59),$pointcolor);
}
//3.画干扰线
for($i=0;$i<3;$i++){
$linecolor=imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,199),mt_rand(1,59),mt_rand(1,199),mt_rand(1,59),$linecolor);
}
header('content-type:image/png');
imagepng($image);
//end
imagedestroy();
<?php
session_start();
$image =imagecreatetruecolor(200,60);
$bgcolor=imagecolorallocate($image,255,255,255);//#ffffff
imagefill($image,0,0,$bgcolor);
$fontface='simfang.ttf';//这里我用仿宋
$str="的一了是我不在人们有来他这上着个地到大里说去子得也和那要下看天时过出小么起你都把好还多没为又可家学只以主会样年想能生同老中从自面前头到它后然走很像见两用她国动进成回什边作对开而已些现山民候经发工向事命给长水几义三声于高正妈手知理眼志点心战二问但身方实吃做叫当住听革打呢真党全才四已所敌之最光产情路分总条白话东席次亲如被花口放儿常西气五第使写军吧文运在果怎定许快明行因别飞外树物活部门无往船望新带队先力完间却站代员机更九您每风级跟笑啊孩万少直意夜比阶连车重便斗马哪化太指变社似士者干石满决百原拿群究各六本思解立河爸村八难早论吗根共让相研今其书坐接应关信觉死步反处记将千找争领或师结块跑谁草越字加脚紧爱等习阵怕月青半火法题建赶位唱海七女任件感准张团屋爷离色脸片科倒睛利世病刚且由送切星晚表够整认响雪流未场该并底深刻平伟忙提确近亮轻讲农古黑告界拉名呀土清阳照办史改历转画造嘴此治北必服雨穿父内识验传业菜爬睡兴";//这里字间不能有空格,有在外面删掉再拿进来,注意视图切自动换行
$strdb=str_split($str,3);
/* header('content-type:text/html;charset=utf-8');
var_dump($strdb);//这种打印并中断的方法很实用,要注意
die();//少一个分号都能把自己给搞蒙!! */
//1.画数字(字典)
$captcha_code='';
for($i=0;$i<4;$i++){
$fontcolor = imagecolorallocate($image, mt_rand(0,120), mt_rand(0,120), mt_rand(0,120));
$index=mt_rand(0,count($strdb)-1);
$cn=$strdb[$index];
$captcha_code.=$cn;
imagettftext($image,mt_rand(20,24),mt_rand(-60,60),($i*50+10),mt_rand(35,40),$fontcolor,$fontface,$cn);
}//错误:这里之前少了一个参数“字体大小”;字体大小是20-24,所以i=0的时候X的值太小的话有可能没边,要考虑到。
$_SESSION['authcode']=$captcha_code;
//2.画干扰点
for($i=0;$i<200;$i++){
$pointcolor=imagecolorallocate($image,mt_rand(50,200),mt_rand(50,100),mt_rand(50,200));
imagesetpixel($image,mt_rand(1,199),mt_rand(1,59),$pointcolor);
}
//3.画干扰线
for($i=0;$i<3;$i++){
$linecolor=imagecolorallocate($image,mt_rand(80,220),mt_rand(80,220),mt_rand(80,220));
imageline($image,mt_rand(1,199),mt_rand(1,59),mt_rand(1,199),mt_rand(1,59),$linecolor);
}
header('content-type:image/png');
imagepng($image);
//end
imagedestroy();
session_start(); header('content-type:text/html;charset=utf-8'); // 定义字符集路径 $fontface = "SIMYOU.TTF"; // 定义字符库 $str = "中文字库"; // 如果字符必须保证为 UTF-8 编码格式, 如果不是,需要将其转换UTF-8 编码 // iconv ( string $in_charset , string $out_charset , string $str ) 将 $in_charset 编码的 $str 字符串按要求的 $out_charset 字符编码来转换 并返回 // $str = iconv("GBK", "UTF-8", $text); // 将字符库中的字符截取成数组 // str_split(string,length) 把字符串分割到数组中。string 要分割的字符串。length 每个数组元素的长度。默认是 1。 // 因为 utf-8 编码的字符 是三个字节一个汉字,所以 length = 3. $strdb = str_split($str,3); for ($i=0; $i < 4; $i++) { // 0-120 为深色区,能更好的在浅色背景中识别验证码 $fontcolor = imagecolorallocate($image, rand(0,120), rand(0,120), rand(0,120)); $index = rand(0,count($strdb)-1); $cn = $strdb[$index]; $captch .=$cn; // imagettftext ( 画布资源 , 字体大小 , 倾斜角度 , X轴位置 , Y轴位置 , 字体颜色 , 字符集路径 , 文字内容 ) 图像写入文本 imagettftext($image, rand(14,18), mt_rand(-60,60), (40*$i+20), mt_rand(30,35), $fontcolor, $fontface, $cn); } // 保存验证码,并全部转换在小写 $_SESSION['authcode'] = strtolower($captch);
header("content-type:text/html;charset=utf-8");代表浏览器输出文本类型
在form_xxx.php 中 或者将 php代码 包含到 <body> 中,或者在 php代码最前面加上 header('content-type:text/html;charset=utf-8'); 这样浏览器才能正确处理 $_SESSION['authcode'] 和 $_REQUEST['authcode']中可能出现的汉字 captch_img.php 中的代码: session_start(); //开启 session 功能 $table = array( //制作 验证图 验证码 对照表 'pic0'=>'猫', 'pic1'=>'狗', 'pic2'=>'蛇', 'pic3'=>'马' ); $index = rand(0,3); //生成随机数 $value = $table['pic'.$index]; //获取对应验证码 $_SESSION['authcode'] = $value; //保存验证码 $filename = dirname(__FILE__).'\\pic'.$index.'.jpg'; //获取验证图文件路径 $contents = file_get_contents($filename); //获取验证图内容 header('content-type:image/jpg'); //填写报头 echo $contents; //输出验证图
动图更换验证码通过javascript修改 src地址,通过改变传入的参数,从而刷新验证码 <a href = "javascript:void(0)" onclick = "document.getElementById('captcha_img').src = './captcha.php?r='+Math.random()">换一个?</a>
strtolower()将字符串转为小写
if(isset($_REQUEST['authcode'])){ session_start(); if(strtolower($_REQUEST['authcode'])==$_SESSION['authcode']){ echo '<font color="#0000CC">输入正确</font>'; }else{ echo '<font color="#CC0000"> <b>输入错误</b> </font>'; } exit(); }