当前位置:Gxlcms > PHP教程 > PHP之验证码识别,php验证码_PHP教程

PHP之验证码识别,php验证码_PHP教程

时间:2021-07-01 10:21:17 帮助过:21人阅读

PHP之验证码识别,php验证码


首先推荐几篇有关验证码识别的文章,觉得不错

php实现验证码的识别(初级篇)

关于bp神经网格识别验证码

一、思路

碰见一个验证码,如果我们想要识别它,我们需要的是做什么呢?
我们先观察几个验证码............


我们用人眼去观察,会很显然的认出验证码所包含的字符,那么人眼的“识别机理”是什么呢?
大概是验证码图片字符的背景的颜色区别吧,试想,如果字符和背景没有颜色区别,我们能够判断验证码吗,很显然不能。

所以,我们就可以从人出发。

先从图片的颜色着手,即图片的RGB信息。

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

定义函数取得RGB信息

 1 //代码本来是一个类,现在拆开来写的,有可能有不严谨的地方,大家可以看得懂就好了
 2 
 3 /*
 4  *取得图片路径和图片尺寸
 5  */
 6 $this->ImagePath = $Image;
 7 $this->ImageSize = getimagesize($Image);
 8 
 9 /*
10  *获取图像标识符,保存到ImageInfo,只能处理bmp,png,jpg图片
11  *ImageCreateFromBmp是我自己定义的函数,最后会给出
12  */
13 function getInfo(){
14     $filetype = substr($this->ImagePath,-3);
15     if($filetype == 'bmp'){
16         $this->ImageInfo = $this->ImageCreateFromBmp($this->ImagePath);
17     }elseif($filetype == 'jpg'){
18         $this->ImageInfo = imagecreatefromjpeg($this->ImagePath);    
19     }elseif($filetype == 'png'){
20         $this->ImageInfo = imagecreatefrompng($this->ImagePath);    
21     }
22 }
23 
24 /*获取图片RGB信息*/
25 function getRgb(){
26     $rgbArray = array();
27     $res = $this->ImageInfo;
28     $size = $this->ImageSize;
29     $wid = $size['0'];
30     $hid = $size['1'];
31     for($i=0; $i < $hid; ++$i){
32         for($j=0; $j < $wid; ++$j){
33             $rgb = imagecolorat($res,$j,$i);
34             $rgbArray[$i][$j] = imagecolorsforindex($res, $rgb);
35         }
36     }
37     return $rgbArray;
38 }

二、二值化

因为人眼可以分别出验证码,所以验证码的RGB信息就会有一定的特点,这时候需要我们观察一下,直接打印RGB数组是不好观察的…………,好多数啊

在php实现验证码的识别(初级篇)中,作者的判断依据是

无论验证数字颜色如何变化,该数字的 RGB 值总有一个值小于 125

我们先获取他的灰度,再判断

 1 /*
 2  *获取灰度信息
 3  */
 4 function getGray(){
 5     $grayArray = array();
 6     $size = $this->ImageSize;
 7     $rgbarray = $this->getRgb();
 8     $wid = $size['0'];
 9     $hid = $size['1'];
10     for($i=0; $i < $hid; ++$i){
11         for($j=0; $j < $wid; ++$j){
12             $grayArray[$i][$j] = (299*$rgbarray[$i][$j]['red']+587*$rgbarray[$i][$j]['green']+144*$rgbarray[$i][$j]['blue'])/1000;
13         }
14     }
15     return $grayArray;
16 }

然后我们根据灰度信息,打印图片,注意不是打印灰度信息

 1 /*根据灰度信息打印图片*/
 2 function printByGray(){
 3     $size = $this->ImageSize;    
 4     $grayArray = $this->getGray();
 5     $wid = $size['0'];
 6     $hid = $size['1'];
 7     for($k=0;$k<25;$k++){
 8         echo $k."\n";
 9         for($i=0; $i < $hid; ++$i){
10             for($j=0; $j < $wid; ++$j){
11                 if($grayArray[$i][$j] < $k*10){
12                     echo '■';
13                 }else{
14                     echo '□';
15                 }
16             }
17             echo "|\n";
18         }
19         echo "---------------------------------------------------------------------------------------------------------------\n";
20     }
21     
22 }

注意到,从$grayArray[$i][$j] < 80就会有显然的输出,我们观察选择了一个恰当的阈值,得到一个0101的数组,我们已经将我们的图片转化为了字符(1)和背景(0),即二值化。

 1 /*
 2  *根据自定义的规则,获取二值化二维数组
 3  *@return  图片高*宽的二值数组(0,1)
 4  */
 5 function getErzhi(){
 6     $erzhiArray = array();
 7     $size = $this->ImageSize;
 8     $grayArray = $this->getGray();
 9     $wid = $size['0'];
10     $hid = $size['1'];
11     for($i=0; $i < $hid; ++$i){
12         for($j=0; $j <$wid; ++$j){
13             if( $grayArray[$i][$j]    < 90 ){
14                 $erzhiArray[$i][$j]=1;
15             }else{
16                 $erzhiArray[$i][$j]=0;
17             }
18         }
19     }
20     return $erzhiArray;
21 }

三、去除噪点

但是我们发现有一些小点影响了我们的判断

我们可以注意到这些事干扰噪点,但是如果我们是机器的话,我们如何判断这些点是否是字符呢?

所以接下来,我们需要将这些字符去除。

我们判断,如果一个黑点的上下左右的八个点全部是白,我们就认为它是噪点,并予以清除,赋为白

 1 /*
 2  *二值化图片降噪
 3  *@param $erzhiArray二值化数组
 4  */
 5 function reduceZao($erzhiArray){
 6     $data = $erzhiArray;
 7     $gao = count($erzhiArray);
 8     $chang = count($erzhiArray['0']);
 9 
10     $jiangzaoErzhiArray = array();
11 
12     for($i=0;$i<$gao;$i++){
13         for($j=0;$j<$chang;$j++){
14             $num = 0;  
15             if($data[$i][$j] == 1)  
16             {
17                 //
18                 if(isset($data[$i-1][$j])){  
19                     $num = $num + $data[$i-1][$j];  
20                 }  
21                 //
22                 if(isset($data[$i+1][$j])){  
23                     $num = $num + $data[$i+1][$j];  
24                 }  
25                 //
26                 if(isset($data[$i][$j-1])){  
27                     $num = $num + $data[$i][$j-1];  
28                 }  
29                 //
30                 if(isset($data[$i][$j+1])){  
31                     $num = $num + $data[$i][$j+1];  
32                 }  
33                 // 上左  
34                 if(isset($data[$i-1][$j-1])){  
35                     $num = $num + $data[$i-1][$j-1];  
36                 }  
37                 // 上右  
38                 if(isset($data[$i-1][$j+1])){  
39                     $num = $num + $data[$i-1][$j+1];  
40                 }  
41                 // 下左  
42                 if(isset($data[$i+1][$j-1])){  
43                     $num = $num + $data[$i+1][$j-1];  
44                 }  
45                 // 下右  
46                 if(isset($data[$i+1][$j+1])){  
47                     $num = $num + $data[$i+1][$j+1];  
48                 }  
49             }
50 
51                 if($num < 1){  
52                     $jiangzaoErzhiArray[$i][$j] = 0;  
53                 }else{
54                     $jiangzaoErzhiArray[$i][$j] = 1;  
55                 }
56         }
57     }
58     return $jiangzaoErzhiArray;    
59 
60 }

我们发现噪点消失了。

四、分割

这个时候,我们就需要对单一数字字母进行操作了,我们先将数字提取出来。

有些验证码字符相连,特别难!!!

我们分别从左到右,从右到左,从上到下,从下到上,进行扫描,去除白点,找到边框。

 1 /*
 2  *归一化处理,针对一个个的数字,即去除字符周围的白点
 3  *@param $singleArray 二值化数组
 4  */
 5 function getJinsuo($singleArray){
 6     $dianCount = 0;
 7     $rearr = array();
 8     
 9     $gao = count($singleArray);
10     $kuan = count($singleArray['0']);
11     
12     $dianCount = 0;
13     $shangKuang = 0;
14     $xiaKuang = 0;
15     $zuoKuang = 0;
16     $youKuang = 0;
17     //从上到下扫描
18     for($i=0; $i < $gao; ++$i){
19         for($j=0; $j < $kuan; ++$j){
20             if( $singleArray[$i][$j] == 1){
21                 $dianCount++;
22             }
23         }
24         if($dianCount>1){
25             $shangKuang = $i;
26             $dianCount = 0;
27             break;
28         }
29     }
30     //从下到上扫描
31     for($i=$gao-1; $i > -1; $i--){
32         for($j=0; $j < $kuan; ++$j){
33             if( $singleArray[$i][$j] == 1){
34                 $dianCount++;
35             }
36         }
37         if($dianCount>1){
38             $xiaKuang = $i;
39             $dianCount = 0;
40             break;
41         }
42     }
43     //从左到右扫描
44     for($i=0; $i < $kuan; ++$i){
45         for($j=0; $j < $gao; ++$j){
46             if( $singleArray[$j][$i] == 1){
47                 $dianCount++;
48             }
49         }
50         if($dianCount>1){
51             $zuoKuang = $i;
52             $dianCount = 0;
53             break;
54         }
55     }
56     //从右到左扫描
57     for($i=$kuan-1; $i > -1; --$i){
58         for($j=0; $j < $gao; ++$j){
59             if( $singleArray[$j][$i] == 1){
60                 $dianCount++;
61             }
62         }
63         if($dianCount>1){
64             $youKuang = $i;
65             $dianCount = 0;
66             break;
67         }
68     }
69     for($i=0;$i<$xiaKuang-$shangKuang+1;$i++){
70         for($j=0;$j<$youKuang-$zuoKuang+1;$j++){
71             $rearr[$i][$j] = $singleArray[$shangKuang+$i][$zuoKuang+$j];
72         }
73     }
74     return $rearr;
75 }

然后从左到右扫描,找到字符的分割

返回三维数组,每一维就是一个字符。

 1 /*
 2  *切割成三维数组,每个小数字在一个数组里面
 3  *只适用四个数字一起的数组
 4  *@param 经过归一化处理的二值化数组
 5  */
 6 function cutSmall($erzhiArray){
 7     $doubleArray = array();
 8     $jieZouyou = array();
 9     
10     $gao = count($erzhiArray);
11     $kuan = count($erzhiArray['0']);
12     
13     $jie = 0;
14     $s = 0;
15     $jieZouyou[$s] = 0;
16     $s++;
17     //从左到右扫描
18     
19     for($i=0; $i < $kuan;){
20         for($j=0; $j < $gao; ++$j){
21             $jie = $jie + $erzhiArray[$j][$i];
22         }
23         //如果有一列全部是白,设置$jieZouyou,并且跳过中间空白部分
24         if($jie == 0){
25             $jieZouyou[$s] = $i+1;
26             do{
27                 $n = ++$i;
28                 $qian = 0;
29                 $hou = 0;
30                 for($m=0; $m < $gao; ++$m){
31                     $qian = $qian + $erzhiArray[$m][$n];
32                     $hou = $hou + $erzhiArray[$m][$n+1];                        
33                 }
34                 $jieZouyou[$s+1] = $n+1;
35             }
36             //当有两列同时全部为白,说明有间隙,循环,知道间隙没有了
37             while($qian == 0 && $hou == 0);
38             $s+=2;
39             $i++;
40         }else{
41             $i++;    
42         }
43         
44         $jie = 0;
45     }
46     $jieZouyou[] = $kuan;
47     //极端节点数量,(应该是字符个数)*2
48     $jieZouyouCount = count($jieZouyou);
49     
50     for($k=0;$k<$jieZouyouCount/2;$k++){
51         for($i=0; $i < $gao; $i++){
52             for($j=0; $j < $jieZouyou[$k*2+1]-$jieZouyou[$k*2]-1; ++$j){
53                 $doubleArray[$k][$i][$j] = $erzhiArray[$i][$j+$jieZouyou[$k*2]];
54             }
55         }
56         
57     }
58     return $doubleArray;
59 }

五、倾斜调整

我们发现第三个9有一点倾斜,

我们需要将倾斜的图片“正”过来

人怎么处理的呢,先眼睛观察“倾斜了多少度”,然后把图片扭过来多少度,并且观察->负反馈->大脑传递扭转角度时刻在发生,最后图片就“正”过来了。

人是怎么观察“倾斜”的,以上面的“2”做例子,可能是右上方(左下方)的黑色比左上方(右下方)的多?

我们建立X轴正向向下,Y轴向右的直角坐标系

我们计算每一层的黑点的分布中点坐标,得到一系列离散点,计算这些点所在的直线(线性回归方程的计算,),公式y = b*x+a,

竟然有用到这个公式的一天!!!

大概就是一条倾斜的直线了,通过直线计算直线倾斜角度,然后转这么多的角度,图片应该就“正”了吧。

其中a,b的计算如下

 1 /*
 2  *定义求线性回归A和B的函数
 3  *@param $zuobiaoArray坐标的三维数组
 4  */
 5 function getHuigui($zuobiaoArray){
 6     $y8 = 0;
 7     $x8 = 0;
 8     $x2 = 0;
 9     $xy = 0;
10     $geshu = count($zuobiaoArray);
11     for($i=0;$i<$geshu;$i++){
12         $y8 = $y8+$zuobiaoArray[$i]['y'];
13         $x8 = $x8+$zuobiaoArray[$i]['x'];
14         $xy = $xy+$zuobiaoArray[$i]['y']*$zuobiaoArray[$i]['x'];
15         $x2 = $x2 + $zuobiaoArray[$i]['x']*$zuobiaoArray[$i]['x'];;
16     }
17     $y8 = $y8/$geshu;
18     $x8 = $x8/$geshu;
19     
20     $b = ($xy-$geshu*$y8*$x8)/($x2-$geshu*$x8*$x8);
21     $a = $y8-$b*$x8;
22     $re['a'] = $a;
23     $re['b'] = $b;
24     return $re;
25     //y = b * x + a
26 }

怎么转角?

1、可以直接对图片进行操作,但是发现有比较大的失真,就没有继续了。
2、或者,对黑点白点的坐标进行操作……

这就是三角函数了,好长时间不碰三角函数,都差点忘记了。

定义函数

 1 /*
 2  *定义转化坐标的函数
 3  *@param $x x坐标即$i
 4  *@param $y y坐标,即j
 5  *@param $b 线性回归方程的b参数 
 6  */ 
 7 function getNewZuobiao($x,$y,$b){
 8     if($x == 0){
 9         if($y>0){
10             $xianJiao = M_PI/2;
11         }elseif($y<0){
12             $xianJiao = -M_PI/2;
13         }else{
14             $p['x'] = 0;
15             $p['y'] = 0;
16             return $p;
17         }
18     }else{
19         $xianJiao = atan($y/$x);    
20     }
21     $jiao =$xianJiao-atan($b);
22     $chang = sqrt($x*$x+$y*$y);
23     $p['x'] = $chang*cos($jiao);
24     $p['y'] = $chang*sin($jiao);
25     return $p;
26 }

转角吧

 1 /*
 2  *对【单个】数字的二值化二维数组进行倾斜调整
 3  *@param  $singleArray  高*宽的二值数组(0,1)
 4  */
 5 function singleSlopeAdjust($singleErzhiArray){
 6     $slopeArray = array();
 7     $gao = count($singleErzhiArray);
 8     $chang = count($singleErzhiArray['0']);
 9     
10     //初始化$slopeArray
11     for($i=0;$i<$gao*4;$i++){
12         for($j=0;$j<$chang*4;$j++){
13             $slopeArray[$i][$j] = 0;
14         }
15     }
16     
17     //初始化中心坐标(是数组的下标)
18     $centerXfoalt = ($gao-1)/2;
19     $centerYfoalt = ($chang-1)/2;
20     $centerX = ceil($centerXfoalt);
21     $centerY = ceil($centerYfoalt);
22     
23     //初始化图片倾斜诶角度
24     /*斜率的计算!!!!!,回归方程*/
25     //从上到下扫描,计算中点,求得一串坐标($i,$ava)
26     for($i=0;$i<$gao;$i++){
27         $Num = 0;
28         $Amount = 0;
29         for($j=0;$j<$chang;$j++){
30             if($singleErzhiArray[$i][$j] == 1){
31                 $Num = $Num+$j;
32                 $Amount++;
33             }
34         }
35         if($Amount == 0){
36             $Ava[$i] = $chang/2;    
37         }else{
38             $Ava[$i] = $Num/$Amount;
39         }
40     }
41 
42     
43     //计算线性回归方程的b与a
44     $zuo = array();
45     for($j=0;$j<count($Ava);$j++){
46         $zuo[$j]['x'] = $j;
47         $zuo[$j]['y'] = $Ava[$j];
48     }
49     $res = $this->getHuigui($zuo);
50     $zuoB = $res['b'];
51 
52     
53     for($i=0;$i<$gao;$i++){
54         for($j=0;$j<$chang;$j++){
55             if($singleErzhiArray[$i][$j] == 1){
56                 $splodeZuobiao = $this->getNewZuobiao($i,$j,$zuoB);
57                 $splodeX = $splodeZuobiao['x'];
58                 $splodeY = $splodeZuobiao['y'];
59                 $slopeArray[$splodeX+$gao][$splodeY+$chang] = 1;
60             }
61         }
62     }
63     
64     //将预处理的数组空白清理
65     $slopeArray = $this->getJinsuo($slopeArray);
66     return $slopeArray;
67 }

看到正了一些

六、统一大小

上文中因为各种操作,每个字符大小不一,我们需要统一大小

七、特征值的建立

有很多方法

1、逐像素特征提取法
这是一种最简单的特征提取方法。它可以对图像进行逐行逐列的扫描,当遇到黑色像素时取其特征值为1,遇到白色像素时取其特征值为0,这样当扫描结束后就获得一个维数与图像中的像素点的个数相同的特征向量矩阵。
这种方法提取的信息量最大,但是它的缺点也很明显,就是适应性不强。

2、骨架特征提取法
两幅图像由于它们的线条的粗细不同,使得两幅图像差别很大,但是将它们的线条进行细化后,统一到相同的宽度,如一个像素宽时,这是两幅图像的差距就不那么明显。利用图形的骨架作为特征来进行数码识别,就使得识别有了一定的适应性。一般使用细化的方法来提取骨架,细化的算法有很多,如Hilditch算法、Rosenfeld算法等。对经过细化的图像利用EveryPixel函数进行处理就可以得到细化后图像的特征向量矩阵。骨架特征提取的方法对于线条粗细不同的数码有一定的适应性,但是图像一旦出现偏移就难以识别。

3、微结构法
微结构法将图像分为几个小块,统计每个小块的像素分布。本文提取出汉字的39个特征,存储在数组f[0]~f[38]中。具体算法可分为四步:

步骤一:把字符平均分成9份,如图4.1所示,给每一份编号如图4.2,统计每一份内黑色像素的个数,存储在数字tz[0]~tz[9]中,统计在行方向和列方向上每一份内的黑色像素个数和与之相邻的一份内黑色像素个数的比值作为一个特征,例如:行方向上提取特征f[0]=tz[1]/ tz[0],f[1]=tz[2]/ tz[1],f[2]=tz[0]/ tz[2],…,f[8]=tz[6]/ tz[8];列方向上f[9]=tz[3]/ tz[0],f[10]=tz[6]/ tz[3],f[11]=tz[0]/ tz[6],…,f[17]=tz[2]/ tz[8],共18个特征。

步骤二:把字符横向分成三份,如图4.3所示,统计每一份内的黑色像素个数,每一份内的黑色像素个数与前一份内黑色像素个数的比值作为一个特征,f[18]=tz[10]/ tz[9],f[19]=tz[11]/ tz[10],f[20]=tz[9]/ tz[11];把字符纵向分成三份,如图4.4所示,统计每一份内的黑色像素个数,每一份内的黑色像素个数与前一份内黑色像素个数的比值作为一个特征,f[21]=tz[13]/ tz[12],f[22]=tz[14]/ tz[13],f[23]=tz[12]/ tz[14];共六个特征。

步骤三:如图4.5,在竖直方向上找出三列,统计在该列中跳变点的个数,即相邻点像素值从0变到255的次数,共三个特征,记为f[24],f[25],f[26];在水平方向上找出三行列,统计在该行中跳变点的个数,即相邻点象素值从0变到255的次数,共三个特征,记为f[27],f[28],f[29]。

图4.5

步骤四:把每一份内黑色象素的个数tz[0]~tz[9],作为9个特征,记为:f[30]~f[38]。

这样得到汉字的共39个特征,根据这些特征就可以区分每个车牌汉字,进行识别。

我们使用最简单的逐像素特征提取法。

多多增加数据库,识别率会增加的

八、识别验证码

对于一个新的验证码,进行上文操作,然后对比数据库就可以了

 1 /*
 2  *进行匹配
 3  *@param  $Image  图片路径
 4  */
 5 public function run($Image){
 6     $data = array('','','','');
 7     $result="";
 8     $bilu = '';
 9     $maxarr = '';
10     
11     //提取特征
12     $this->prepare($Image);
13     $yuanshi = $this->getErzhi();
14     $yijijiangzao = $this->reduceZao($yuanshi);
15     $small = $this->cutSmall($yijijiangzao);
16     for($k=0;$k<4;$k++){
17         $tianchong = $this->tianChong($small[$k]);
18         $tiaozhenjiaodu = $this->singleSlopeAdjust($tianchong);
19         $tongyidaxiao = $this->tongyiDaxiao($tiaozhenjiaodu);
20         for($i=0;$i<20;$i++){
21             for($j=0;$j<20;$j++){
22                 $data[$k] .= $tongyidaxiao[$i][$j];    
23             }    
24         }
25     }
26 
27     // 进行关键字匹配
28     foreach($data as $numKey => $numString)
29     {
30 
31         $max = 0;
32         $num = 0;
33         foreach($this->Keys as $value => $key)
34         {
35             similar_text($value, $numString,$percent);
36             if($percent > $max)
37             {
38                 $max = $percent;
39                 $num = $key;
40                 $zim = $value;
41             }
42             if($max>95){
43                 break;
44             }
45         }
46         $result .=$num;
47         $maxarr[] = $max;
48     }
49     // 查找最佳匹配数字
50     $re = $maxarr;
51     $re[] = $result;
52     return $re;
53     //return $result.'|max|一:'.$maxarr['0'].'|二:'.$maxarr['1'].'|三:'.$maxarr['2'].'|四:'.$maxarr['3'];
54 }

试试:


PHP图形验证码识别

Header("Content-type: image/gif");
/*
* 初始化
*/
$border = 0; //是否要边框 1要:0不要
$how = 4; //验证码位数
$w = $how*15; //图片宽度
$h = 20; //图片高度
$fontsize = 5; //字体大小
$alpha = "abcdefghijkmnopqrstuvwxyz"; //验证码内容1:字母
$number = "023456789"; //验证码内容2:数字
$randcode = ""; //验证码字符串初始化
srand((double)microtime()*1000000); //初始化随机数种子

$im = ImageCreate($w, $h); //创建验证图片

/*
* 绘制基本框架
*/
$bgcolor = ImageColorAllocate($im, 255, 255, 255); //设置背景颜色
ImageFill($im, 0, 0, $bgcolor); //填充背景色
if($border)
{
$black = ImageColorAllocate($im, 0, 0, 0); //设置边框颜色
ImageRectangle($im, 0, 0, $w-1, $h-1, $black);//绘制边框
}

/*
* 逐位产生随机字符
*/
for($i=0; $i<$how; $i++)
{
$alpha_or_number = mt_rand(0, 1); //字母还是数字
$str = $alpha_or_number ? $alpha : $number;
$which = mt_rand(0, strlen($str)-1); //取哪个字符
$code = substr($str, $which, 1); //取字符
$j = !$i ? 4 : $j+15; //绘字符位置
$color3 = ImageColorAllocate($im, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100)); //字符随即颜色
ImageChar($im, $fontsize, $j, 3, $code, $color3); //绘字符
$randcode .= $code; //逐位加入验证码字符串
}

/*
* 添加干扰
*/
for($i=0; $i<5; $i++)//绘背景干扰线
{
$color1 = ImageColorAllocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255)); //干扰线颜色
ImageArc($im, mt_ra......余下全文>>
 

PHP 验证码识别 或者ASP程序也行怎写程序识别

原理不难,只需通过PHP来生成一张图片!在这张图片上通过PHP的图片处理函数在图片上写几个字符就Ok啦!在写字符时注意将写的字符记录下,这个记录是通过session来做!然后在验证时直接调用$_SESSION变量就可以了!

具体的代码如下:
有两个文件
yangzhengma.php用来显示图片和验证输入的验证码

session_start();
if(!empty($_GET['sub'])){
if($_SESSION['checks'] == $_GET['ma']){
echo "验证码正确";
}else{
echo "验证码不正确!";
}
}
?>


<br /> 验证码实例<br /> </title><br /> <meta http-equiv="content-type" content="text/html;charset=utf-8"/><br /></head><br /><body><br /> <img src="https://www.gxlcms.com/check.php" border="0"/><br /> <br/><br /> <form method="get" action=""><br /> 请输入验证码:<input type="text" id="ma" name="ma"/><br /> <input type="submit" id="sub" name="sub" value="验证"/><br /> </form><br /></body><br /></html><br /><br />注意图片的地址写到PHP生成图片的文件地址<br /><br />https://www.gxlcms.com/check.php用来生成图片<br /><br /><?php<br /> session_start();<br /> header('content-type:image/jpeg');<br /> $image_width=70;<br /> $image_height=25;<br /> $str="";<br /> $arr=array(1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z');<br /> for ($i =0 ; $i ......余下全文>><br/>  </br></p> <p align="left"><span id="url" itemprop="url">http://www.bkjia.com/PHPjc/857272.html</span><span id="indexUrl" itemprop="indexUrl">www.bkjia.com</span><span id="isOriginal" itemprop="isOriginal">true</span><span id="isBasedOnUrl" itemprop="isBasedOnUrl">http://www.bkjia.com/PHPjc/857272.html</span><span id="genre" itemprop="genre">TechArticle</span><span id="description" itemprop="description">PHP之验证码识别,php验证码 首先推荐几篇有关验证码识别的文章,觉得不错 php实现验证码的识别(初级篇) 关于bp神经网格识别验证码 一、思...</span></p> </div> <div class=""> <ul class="m-news-opt fix"> <li class="opt-item"> <a href='/PHPjiqiao-156583.html' target='_blank'><p>< 上一篇</p><p class="ellipsis">php画一个背景透明,且开始处旋转到在圆的正下方处的一个圆饼统计图_PHP教程</p></a> </li> <li class="opt-item ta-r"> <a href='/PHPjiqiao-156585.html' target='_blank'><p>下一篇 ></p><p class="ellipsis">PHP引用操作以及外部操作函数的局部静态变量的方法_PHP教程</p></a> </li> </ul> </div> </div> </div> <div class="g-title fix"> <h2 class="title-txt">人气教程排行</h2> </div> <div class="m-rank u-dashed mb40"> <ul> <li class="rank-item"> <a href="/PHPjiqiao-379253.html" title='php如何获取跳转前的url' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num top">1</span> php如何获取跳转前的url </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-379019.html" title='php格林威治时间转换成当前时间的方法' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num second">2</span> php格林威治时间转换成当前时间的方法 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-366629.html" title='为什么php不能做大型系统?' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num third">3</span> 为什么php不能做大型系统? </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-207623.html" title='range函数怎么用' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">4</span> range函数怎么用 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-162433.html" title='php中计算页面加载时间几种方法总结_PHP教程' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">5</span> php中计算页面加载时间几种方法总结_PHP教程 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-140221.html" title='求帮助,关于paypal支付返回值修改订单状态' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">6</span> 求帮助,关于paypal支付返回值修改订单状态 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-103588.html" title='typecho怎么配置文章内容页?' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">7</span> typecho怎么配置文章内容页? </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-99213.html" title='PhpStorm左侧structure不显示文件的方法列表是这么回事?' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">8</span> PhpStorm左侧structure不显示文件的方法列表是这么回事? </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-92208.html" title='查看PHP的环境变量_PHP' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">9</span> 查看PHP的环境变量_PHP </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-170.html" title='PHP Primary script unknown 解决方法总结' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">10</span> PHP Primary script unknown 解决方法总结 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-148.html" title='php的命名空间与自动加载实现方法' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">11</span> php的命名空间与自动加载实现方法 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-133.html" title='解决laravel 出现ajax请求419(unknown status)的问题' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">174次</span> <span class="g-sort-num ">12</span> 解决laravel 出现ajax请求419(unknown status)的问题 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-462817.html" title='php 如何删除mysql记录' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">13</span> php 如何删除mysql记录 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-388448.html" title='PHP如何替换数组中的指定元素' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">14</span> PHP如何替换数组中的指定元素 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-124270.html" title='怎么去除字符串中非汉字、非字母、非数字的字符' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">15</span> 怎么去除字符串中非汉字、非字母、非数字的字符 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-112291.html" title='mysql如何一次执行多条SQL语句' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">16</span> mysql如何一次执行多条SQL语句 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-110669.html" title='修改header里面的Connection为close解决方法' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">17</span> 修改header里面的Connection为close解决方法 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-153.html" title='PHP基于session.upload_progress 实现文件上传进度显示功能详解' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">18</span> PHP基于session.upload_progress 实现文件上传进度显示功能详解 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-125.html" title='php5.6.x到php7.0.x特性小结' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">173次</span> <span class="g-sort-num ">19</span> php5.6.x到php7.0.x特性小结 </a> </li> <li class="rank-item"> <a href="/PHPjiqiao-378118.html" title='php为什么会出现504错误' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">172次</span> <span class="g-sort-num ">20</span> php为什么会出现504错误 </a> </li> </ul> </div> </div> </div> <!-- / 教程内容页 --> </div> </div> <!-- 页尾 --> <div class="footer"> 本站所有资源全部来源于网络,若本站发布的内容侵害到您的隐私或者利益,请联系我们删除!</div> <!-- / 页尾 --> <script type="text/javascript" src="/kan/js/read.js"></script> <div style="display:none"> <div class="login-box" id="login-dialog"> <div class="login-top"><a class="current" rel="nofollow" id="login1" onclick="setTab('login',1,2);" >登录</a></div> <div class="login-form" id="nav-signin"> <!-- <div class="login-ico"><a rel="nofollow" class="qq" id="qqlogin" target="_blank" href="/user-center-qqlogin.html"> QQ </a></div> --> <div class="login-box-form" id="con_login_1"> <form id="loginform" action="/user-center-login.html" method="post" onsubmit="return false;"> <p class="int-text"> <input class="email" id="username" name="username" type="text" value="用户名或Email" onfocus="if(this.value=='用户名或Email'){this.value='';}" onblur="if(this.value==''){this.value='用户名或Email';};" ></p> <p class="int-text"> <input class="password1" type="password" id="password" name="password" value="******" onBlur="if(this.value=='') this.value='******';" onFocus="if(this.value=='******') this.value='';" > </p> <p class="int-info"> <label class="ui-label"> </label> <label for="agreement" class="ui-label-checkbox"> <input type="checkbox" value="" name="cookietime" id="cookietime" checked="checked" value="2592000"> <input type="hidden" name="notforward" id="notforward" value="1"> <input type="hidden" name="dosubmit" id="dosubmit" value="1">记住我的登录 </label> <a rel="nofollow" class="aright" href="/user-center-forgetpwd.html" target="_blank"> 忘记密码? </a></p> <p class="int-btn"><a rel="nofollow" id="loginbt" class="loginbtn"><span>登录</span></a></p> </form> </div> <form id="regform" action="/user-center-reg.html" method="post"> <div class="login-reg" style="display: none;" id="con_login_2"> <input type="hidden" name="t" id="t"/> <p class="int-text"> <input id="email" name="email" type="text" value="Email" onfocus="if(this.value=='Email'){this.value='';}" onblur="if(this.value==''){this.value='Email';};"></p> <p class="int-text"> <input id="uname" name="username" type="text" value="用户名或昵称" onfocus="if(this.value=='用户名或昵称'){this.value='';}" onblur="if(this.value==''){this.value='用户名或昵称';};"></p> <p class="int-text"> <input type="password" id="pwd" name="password" value="******" onBlur="if(this.value=='') this.value='******';" onFocus="if(this.value=='******') this.value='';"> </p> <p class="int-text1"><span class="inputbox"> <input id="validate" name="validate" type="text" value="验证码" onfocus="if(this.value=='验证码'){this.value='';}" onblur="if(this.value==''){this.value='验证码';};"> </span><span class="yzm-img"><img src="/user-checkcode-index" alt="看不清楚换一张" id="indexlogin"></p> <p class="int-info"> <label> <input value="" name="agreement" id="agreement" CHECKED="checked" type="checkbox"> 我已阅读<a rel="nofollow" href="/user-center-agreement.html">用户协议</a>及<a rel="nofollow" href="/user-center-agreement.html">版权声明</a></label> </p> <p class="int-btn"><input type="hidden" name="dosubmit"/> <a rel="nofollow" class="loginbtn" id="register"><span>注册</span></a></p> </div> </form> </div> </div> </div> </div> <script type="text/javascript" src="/kan/js/foot_js.js"></script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?6dc1c3c5281cf70f49bc0bc860ec24f2"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <script type="text/javascript" src="/layui/layui.js"></script> <script> layui.use('code', function() { layui.code({ elem: 'pre', //默认值为.layui-code about: false, skin: 'notepad', title: 'php怎么实现数据库验证跳转代码块', encode: true //是否转义html标签。默认不开启 }); }); </script> </body> </html>