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

原创 2016年08月29日 09:51:04

近期研究一些突破验证码方面的知识,记录下来。一方面算是对这几天学习知识的总结帮助自己理解;另一方面希望对研究这方面的技术同学有所帮助;另外也希望引起网站管理者的注意,在提供验证码时多些考虑进去。由于刚刚接触这方面的知识,理解比较浅显,有错误再所难免,欢迎拍砖。
验证码的作用: 有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。其实现代的验证码一般是防止机器批量注册的,防止机器批量发帖回复。目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。
所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。 
我们最常见的验证码
1,四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。
2,随机数字图片验证码。图片上的字符比较中规中矩,有的可能加入一些随机干扰素,还有一些是随机字符颜色,验证作用比上一个好。没有基本图形图像学知识的人,不可破!
3,各种图片格式的随机数字+随机大写英文字母+随机干扰像素+随机位置。 
4,汉字是注册目前最新的验证码,随机生成,打起来更难了,影响用户体验,所以,一般应用的比较少。
简单起见,我们这次说明的主要对象是第2种类型的,我们先看几种网上比较常见的这种验证码的图片.

(不知道怎么搞的,CSDN又不能上传图片了,我把这四种图片放到下载包中了,可以下载下来对比察看)
这四种样式,基本上能代表2中所提到的验证码类型,初步看起来第一个图片最容易破解,第二个次之,第三个更难,第四个最难。
真实情况那?其实这三种图片破解难度相同。
第一个图片,最容易,图片背景和数字都使用相同的颜色,字符规整,字符位置统一。
第二个图片,看似不容易,其实仔细研究会发现其规则,背景色和干扰素无论怎么变化,验证字符字符规整,颜色相同,所以排除干扰素非常容易,只要是非字符色素全部排除即可。
第三个图片,看似更复杂,处理上面提到背景色和干扰素一直变化外,验证字符的颜色也在变化,并且各个字符的颜色也各不相同。看似无法突破这个验证码,本篇文章,就一这种类型验证码为例说明,第四个图片,同学们自己搞。
第四个图片,除了第三个图片上提到的特征外,又在文字上加了两条直线干扰率,看似困难其实,很容易去掉。
验证码识别一般分为以下几个步骤:
1. 取出字模
2. 二值化
3. 计算特征
4. 对照样本
1:取出字模
识别验证码,毕竟不是专业的OCR识别,并且,由于各个网站的验证码各不相同,所以,最常见的方法就是就是建立这个验证码的特征码库。去字模时,我们需要多下载几张图片,使这些图片中,包括所有的字符,我们这里的字母只有图片,所以,只要收集到包括0-9的图片即可。
2:二值化
二值化就是把图片上的验证数字上每个象素用一种数字表示1,其他部分用0表示。这样就可以计算出每个数字字模,记录下这些字模来,当作key即可。
3:计算特征
把要识别的图片,进行二值化,得到图片特征。
4:对照样本
把步骤3种的图片特征码和验证码的字模进行对比,得到验证图片上的数字。
使用目前这种方法,对验证码的识别基本上可以做到100%。
通过以上步骤,您可能说了,并没有发现如何取出干扰素啊!其实取出干扰素的方法很简单,干扰素的一个重要特征是,不能影响验证码的显示效果,所以制作干扰素时它的RGB可能低于或者高于某个特定值,比如我给的例子中的图片,干扰素的RGB各项值是不会超过125的,所以,这样我们就很容易去掉干扰素了。
php代码


[php] view plain copy
  1. <?php  
  2. define('WORD_WIDTH',9);  
  3. define('WORD_HIGHT',13);  
  4. define('OFFSET_X',7);  
  5. define('OFFSET_Y',3);  
  6. define('WORD_SPACING',4);  
  7. class valite  
  8. {  
  9.     public function setImage($Image)  
  10.     {  
  11.         $this->ImagePath = $Image;  
  12.     }  
  13.     public function getData()  
  14.     {  
  15.         return $data;  
  16.     }  
  17.     public function getResult()  
  18.     {  
  19.         return $DataArray;  
  20.     }  
  21.     public function getHec()  
  22.     {  
  23.         $res = imagecreatefromjpeg($this->ImagePath);  
  24.         $size = getimagesize($this->ImagePath);  
  25.         $data = array();  
  26.         for($i=0; $i < $size[1]; ++$i)  
  27.         {  
  28.             for($j=0; $j < $size[0]; ++$j)  
  29.             {  
  30.                 $rgb = imagecolorat($res,$j,$i);  
  31.                 $rgbarray = imagecolorsforindex($res$rgb);  
  32.                 if($rgbarray['red'] < 125 || $rgbarray['green']<125  
  33.                 || $rgbarray['blue'] < 125)  
  34.                 {  
  35.                     $data[$i][$j]=1;  
  36.                 }else{  
  37.                     $data[$i][$j]=0;  
  38.                 }  
  39.             }  
  40.         }  
  41.         $this->DataArray = $data;  
  42.         $this->ImageSize = $size;  
  43.     }  
  44.     public function run()  
  45.     {  
  46.         $result="";  
  47.         // 查找4个数字  
  48.         $data = array("","","","");  
  49.         for($i=0;$i<4;++$i)  
  50.         {  
  51.             $x = ($i*(WORD_WIDTH+WORD_SPACING))+OFFSET_X;  
  52.             $y = OFFSET_Y;  
  53.             for($h = $y$h < (OFFSET_Y+WORD_HIGHT); ++ $h)  
  54.             {  
  55.                 for($w = $x$w < ($x+WORD_WIDTH); ++$w)  
  56.                 {  
  57.                     $data[$i].=$this->DataArray[$h][$w];  
  58.                 }  
  59.             }  
  60.               
  61.         }  
  62.         // 进行关键字匹配  
  63.         foreach($data as $numKey => $numString)  
  64.         {  
  65.             $max=0.0;  
  66.             $num = 0;  
  67.             foreach($this->Keys as $key => $value)  
  68.             {  
  69.                 $percent=0.0;  
  70.                 similar_text($value$numString,$percent);  
  71.                 if(intval($percent) > $max)  
  72.                 {  
  73.                     $max = $percent;  
  74.                     $num = $key;  
  75.                     if(intval($percent) > 95)  
  76.                         break;  
  77.                 }  
  78.             }  
  79.             $result.=$num;  
  80.         }  
  81.         $this->data = $result;  
  82.         // 查找最佳匹配数字  
  83.         return $result;  
  84.     }  
  85.     public function Draw()  
  86.     {  
  87.         for($i=0; $i<$this->ImageSize[1]; ++$i)  
  88.         {  
  89.             for($j=0; $j<$this->ImageSize[0]; ++$j)  
  90.             {  
  91.                 echo $this->DataArray[$i][$j];  
  92.             }  
  93.             echo "/n";  
  94.         }  
  95.     }  
  96.     public function __construct()  
  97.     {  
  98.         $this->Keys = array(  
  99.         '0'=>'000111000011111110011000110110000011110000011110000011110000011110000011110000011110000011011000110011111110000111000',  
  100.         '1'=>'000111000011111000011111000000011000000011000000011000000011000000011000000011000000011000000011000011111111011111111',  
  101.         '2'=>'011111000111111100100000110000000111000000110000001100000011000000110000001100000011000000110000000011111110111111110',  
  102.         '3'=>'011111000111111110100000110000000110000001100011111000011111100000001110000000111000000110100001110111111100011111000',  
  103.         '4'=>'000001100000011100000011100000111100001101100001101100011001100011001100111111111111111111000001100000001100000001100',  
  104.         '5'=>  
  105.        '111111110111111110110000000110000000110000000111110000111111100000001110000000111000000110100001110111111100011111000',  
  106.         '6'=>'000111100001111110011000010011000000110000000110111100111111110111000111110000011110000011011000111011111110000111100',  
  107.         '7'=>'011111111011111111000000011000000010000000110000001100000001000000011000000010000000110000000110000001100000001100000',  
  108.         '8'=>'001111100011111110011000110011000110011101110001111100001111100011101110110000011110000011111000111011111110001111100',  
  109.         '9'=>'001111000011111110111000111110000011110000011111000111011111111001111011000000011000000110010000110011111100001111000',  
  110.     );  
  111.     }  
  112.     protected $ImagePath;  
  113.     protected $DataArray;  
  114.     protected $ImageSize;  
  115.     protected $data;  
  116.     protected $Keys;  
  117.     protected $NumStringArray;  
  118. }  
  119. ?>  
  
我做了一个例子,你可以从这里下载 下载
破解完成上面的验证码,我们就可以使用snoopy(比curl要轻量,所以我喜欢)来模拟浏览器器,访问网站了。

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

近期研究一些突破验证码方面的知识,记录下来。一方面算是对这几天学习知识的总结帮助自己理解;另一方面希望对研究这方面的技术同学有所帮助;另外也希望引起网站管理者的注意,在提供验证码时多些考虑进去。由于刚...
  • ugg
  • ugg
  • 2009年03月03日 15:30
  • 33447

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

自动识别简单的不粘连验证码
  • qq_28666081
  • qq_28666081
  • 2015年08月27日 09:04
  • 752

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

 在上篇文章php实现验证码的识别(初级篇)>中,讲了如何识别简单的验证,这里的简单只的是验证码有数字和字母组成,格式统一,每次出现位置固定。这篇文章将继续深入研究识别验证码,这次识别的目标是,验证码...
  • ugg
  • ugg
  • 2009年03月09日 12:39
  • 46429

12306验证码太难,试着用php自己做一个验证码吧!

今年春运买票的朋友们碰上了12306的新验证码,各种吐槽,各种从一堆相似图片中选择答案。最后果然被网友们玩坏了…… 其实验证码很简单,简单说就是一个用xx编程语言处理图片的操作。 大致思路这样的: 定...
  • zmzwll1314
  • zmzwll1314
  • 2016年01月07日 14:32
  • 2154

php 实现验证码的破解

原文地址: http://www.geekso.com/Valite2/ 个人观点: 原文思想可以借鉴,代码不敢恭维。。。 主要流程是: 1. 将验证码图片的内容二值化,即将里面字符或明显的线条所...
  • zzy2011266
  • zzy2011266
  • 2015年01月10日 13:36
  • 1031

PHP实现简单的验证码功能机制

网站的安全性是开发者不可忽视的一个问题,目前使用最多的一种可以提高网站安全性的方法就是使用验证码功能机制,有的仅仅使用一个几位数字字母混乱的验证码,有的进行手机发送短信进行验证,有的使用邮箱发送邮件进...
  • Zhihua_W
  • Zhihua_W
  • 2016年10月12日 17:54
  • 1550

php实现验证码识别入门

今天研究了一下验证码的识别,搜了很多资料,关键点在获取字母或者数字的特征码。 所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证...
  • sinat_31388283
  • sinat_31388283
  • 2016年12月01日 17:11
  • 442

Php实现验证码功能

验证码这样的功能可以说是无处不在了,接下来使用php来实现验证码这样的功能,这里我是将验证码实现抽取到一个类中独立开来,那么后面如果再使用到验证码功能,直接引入该类文件并创建该类的实例,就可以使用验证...
  • u011109042
  • u011109042
  • 2014年09月23日 16:23
  • 7116

使用PHP-curl获取验证码并模拟登录教务系统

首先说一下这篇文章的需求,当我们在一些没有提供验证接口的系统中,需要验证用户身份的时候,就可能需要用户登录当前系统,从而确定该用户是当前系统的合法用户,校园的教务系统就是一个典型的例子,我们通过学生自...
  • zhuxinquan61
  • zhuxinquan61
  • 2017年05月16日 23:38
  • 1938

PHP实例————实现验证码功能

大家都知道,验证码在网站注册,登录以及很多的时候都是必备的功能。没有了验证码,网站的安全性在很大程度上就受到了威胁。所以说,验证码是网站开发过程中不可或缺的一个功能,验证码的效果直接影响到网站的安全性...
  • u012745215
  • u012745215
  • 2014年09月10日 12:25
  • 1748
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:php实现验证码的识别(初级篇)
举报原因:
原因补充:

(最多只允许输入30个字)