设为首页 收藏本站
查看: 325|回复: 0

[经验分享] php实现验证码的识别

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-4-4 11:37:19 | 显示全部楼层 |阅读模式
  近期研究一些突破验证码方面的知识,记录下来。一方面算是对这几天学习知识的总结帮助自己理解;另一方面希望对研究这方面的技术同学有所帮助;另外也希望引起网站管理者的注意,在提供验证码时多些考虑进去。由于刚刚接触这方面的知识,理解比较浅显,有错误再所难免,欢迎拍砖。
验证码的作用: 有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。其实现代的验证码一般是防止机器批量注册的,防止机器批量发帖回复。目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。
所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。
我们最常见的验证码
1,四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。
2,随机数字图片验证码。图片上的字符比较中规中矩,有的可能加入一些随机干扰素,还有一些是随机字符颜色,验证作用比上一个好。没有基本图形图像学知识的人,不可破!
3,各种图片格式的随机数字+随机大写英文字母+随机干扰像素+随机位置。
4,汉字是注册目前最新的验证码,随机生成,打起来更难了,影响用户体验,所以,一般应用的比较少。
简单起见,我们这次说明的主要对象是第2种类型的,我们先看几种网上比较常见的这种验证码的图片.
这三种样式,基本上能代表2中所提到的验证码类型,初步看起来第一个图片最容易破解,第二个次之,第三个更难,第四个最难。
真实情况那?其实这三种图片破解难度相同。
第一个图片,最容易,图片背景和数字都使用相同的颜色,字符规整,字符位置统一。
第二个图片,看似不容易,其实仔细研究会发现其规则,背景色和干扰素无论怎么变化,验证字符字符规整,颜色相同,所以排除干扰素非常容易,只要是非字符色素全部排除即可。
第三个图片,看似更复杂,处理上面提到背景色和干扰素一直变化外,验证字符的颜色也在变化,并且各个字符的颜色也各不相同。看似无法突破这个验证码,本篇文章,就一这种类型验证码为例说明,第四个图片,同学们自己搞。
第四个图片,除了第三个图片上提到的特征外,又在文字上加了两条直线干扰率,看似困难其实,很容易去掉。
验证码识别一般分为以下几个步骤:
1. 取出字模
2. 二值化
3. 计算特征
4. 对照样本
1:取出字模
识别验证码,毕竟不是专业的OCR识别,并且,由于各个网站的验证码各不相同,所以,最常见的方法就是就是建立这个验证码的特征码库。去字模时,我们需要多下载几张图片,使这些图片中,包括所有的字符,我们这里的字母只有图片,所以,只要收集到包括0-9的图片即可。
2:二值化
二值化就是把图片上的验证数字上每个象素用一种数字表示1,其他部分用0表示。这样就可以计算出每个数字字模,记录下这些字模来,当作key即可。
3:计算特征
把要识别的图片,进行二值化,得到图片特征。
4:对照样本
把步骤3种的图片特征码和验证码的字模进行对比,得到验证图片上的数字。
使用目前这种方法,对验证码的识别基本上可以做到100%。
通过以上步骤,您可能说了,并没有发现如何取出干扰素啊!其实取出干扰素的方法很简单,干扰素的一个重要特征是,不能影响验证码的显示效果,所以制作干扰素时它的RGB可能低于或者高于某个特定值,比如我给的例子中的图片,干扰素的RGB各项值是不会超过125的,所以,这样我们就很容易去掉干扰素了。
php代码
view plaincopy to clipboardprint?


  • <?php
  • define('WORD_WIDTH',9);
  • define('WORD_HIGHT',13);
  • define('OFFSET_X',7);
  • define('OFFSET_Y',3);
  • define('WORD_SPACING',4);
  • classvalite
  • {
  • publicfunctionsetImage($Image)
  • {
  • $this->ImagePath=$Image;
  • }
  • publicfunctiongetData()
  • {
  • return$data;
  • }
  • publicfunctiongetResult()
  • {
  • return$DataArray;
  • }
  • publicfunctiongetHec()
  • {
  • $res=imagecreatefromjpeg($this->ImagePath);
  • $size=getimagesize($this->ImagePath);
  • $data=array();
  • for($i=0;$i<$size[1];++$i)
  • {
  • for($j=0;$j<$size[0];++$j)
  • {
  • $rgb=imagecolorat($res,$j,$i);
  • $rgbarray=imagecolorsforindex($res,$rgb);
  • if($rgbarray['red']<125||$rgbarray['green']<125
  • ||$rgbarray['blue']<125)
  • {
  • $data[$i][$j]=1;
  • }else{
  • $data[$i][$j]=0;
  • }
  • }
  • }
  • $this->DataArray=$data;
  • $this->ImageSize=$size;
  • }
  • publicfunctionrun()
  • {
  • $result="";
  • //查找4个数字
  • $data=array("","","","");
  • for($i=0;$i<4;++$i)
  • {
  • $x=($i*(WORD_WIDTH+WORD_SPACING))+OFFSET_X;
  • $y=OFFSET_Y;
  • for($h=$y;$h<(OFFSET_Y+WORD_HIGHT);++$h)
  • {
  • for($w=$x;$w<($x+WORD_WIDTH);++$w)
  • {
  • $data[$i].=$this->DataArray[$h][$w];
  • }
  • }

  • }
  • //进行关键字匹配
  • foreach($dataas$numKey=>$numString)
  • {
  • $max=0.0;
  • $num=0;
  • foreach($this->Keysas$key=>$value)
  • {
  • $percent=0.0;
  • similar_text($value,$numString,$percent);
  • if(intval($percent)>$max)
  • {
  • $max=$percent;
  • $num=$key;
  • if(intval($percent)>95)
  • break;
  • }
  • }
  • $result.=$num;
  • }
  • $this->data=$result;
  • //查找最佳匹配数字
  • return$result;
  • }
  • publicfunctionDraw()
  • {
  • for($i=0;$i<$this->ImageSize[1];++$i)
  • {
  • for($j=0;$j<$this->ImageSize[0];++$j)
  • {
  • echo$this->DataArray[$i][$j];
  • }
  • echo"/n";
  • }
  • }
  • publicfunction__construct()
  • {
  • $this->Keys=array(
  • '0'=>'000111000011111110011000110110000011110000011110000011110000011110000011110000011110000011011000110011111110000111000',
  • '1'=>'000111000011111000011111000000011000000011000000011000000011000000011000000011000000011000000011000011111111011111111',
  • '2'=>'011111000111111100100000110000000111000000110000001100000011000000110000001100000011000000110000000011111110111111110',
  • '3'=>'011111000111111110100000110000000110000001100011111000011111100000001110000000111000000110100001110111111100011111000',
  • '4'=>'000001100000011100000011100000111100001101100001101100011001100011001100111111111111111111000001100000001100000001100',
  • '5'=>
  • '111111110111111110110000000110000000110000000111110000111111100000001110000000111000000110100001110111111100011111000',
  • '6'=>'000111100001111110011000010011000000110000000110111100111111110111000111110000011110000011011000111011111110000111100',
  • '7'=>'011111111011111111000000011000000010000000110000001100000001000000011000000010000000110000000110000001100000001100000',
  • '8'=>'001111100011111110011000110011000110011101110001111100001111100011101110110000011110000011111000111011111110001111100',
  • '9'=>'001111000011111110111000111110000011110000011111000111011111111001111011000000011000000110010000110011111100001111000',
  • );
  • }
  • protected$ImagePath;
  • protected$DataArray;
  • protected$ImageSize;
  • protected$data;
  • protected$Keys;
  • protected$NumStringArray;
  • }
  • ?>

  <?phpdefine('WORD_WIDTH',9);define('WORD_HIGHT',13);define('OFFSET_X',7);define('OFFSET_Y',3);define('WORD_SPACING',4);classvalite{ public function setImage($Image) { $this->ImagePath = $Image; }public function getData() { return $data; } public function getResult(){ return $DataArray; } public function getHec() { $res =imagecreatefromjpeg($this->ImagePath); $size =getimagesize($this->ImagePath); $data = array(); for($i=0; $i <$size[1]; ++$i) { for($j=0; $j < $size[0]; ++$j) { $rgb =imagecolorat($res,$j,$i); $rgbarray = imagecolorsforindex($res, $rgb);if($rgbarray['red'] < 125 || $rgbarray['green']<125 ||$rgbarray['blue'] < 125) { $data[$i][$j]=1; }else{ $data[$i][$j]=0;} } } $this->DataArray = $data; $this->ImageSize = $size; }public function run() { $result=""; // 查找4个数字 $data =array("","","",""); for($i=0;$i<4;++$i) { $x =($i*(WORD_WIDTH+WORD_SPACING))+OFFSET_X; $y = OFFSET_Y; for($h = $y; $h< (OFFSET_Y+WORD_HIGHT); ++ $h) { for($w = $x; $w <($x+WORD_WIDTH); ++$w) { $data[$i].=$this->DataArray[$h][$w]; } } }// 进行关键字匹配 foreach($data as $numKey => $numString) { $max=0.0; $num= 0; foreach($this->Keys as $key => $value) { $percent=0.0;similar_text($value, $numString,$percent); if(intval($percent) >$max) { $max = $percent; $num = $key; if(intval($percent) > 95)break; } } $result.=$num; } $this->data = $result; // 查找最佳匹配数字return $result; } public function Draw() { for($i=0;$i<$this->ImageSize[1]; ++$i) { for($j=0;$j<$this->ImageSize[0]; ++$j) { echo $this->DataArray[$i][$j];} echo "/n"; } } public function __construct() { $this->Keys =array('0'=>'000111000011111110011000110110000011110000011110000011110000011110000011110000011110000011011000110011111110000111000','1'=>'000111000011111000011111000000011000000011000000011000000011000000011000000011000000011000000011000011111111011111111','2'=>'011111000111111100100000110000000111000000110000001100000011000000110000001100000011000000110000000011111110111111110','3'=>'011111000111111110100000110000000110000001100011111000011111100000001110000000111000000110100001110111111100011111000','4'=>'000001100000011100000011100000111100001101100001101100011001100011001100111111111111111111000001100000001100000001100','5'=>'111111110111111110110000000110000000110000000111110000111111100000001110000000111000000110100001110111111100011111000','6'=>'000111100001111110011000010011000000110000000110111100111111110111000111110000011110000011011000111011111110000111100','7'=>'011111111011111111000000011000000010000000110000001100000001000000011000000010000000110000000110000001100000001100000','8'=>'001111100011111110011000110011000110011101110001111100001111100011101110110000011110000011111000111011111110001111100','9'=>'001111000011111110111000111110000011110000011111000111011111111001111011000000011000000110010000110011111100001111000',); } protected $ImagePath; protected $DataArray; protected $ImageSize;protected $data; protected $Keys; protected $NumStringArray;}?>
我做了一个例子,你可以从这里下载 下载
破解完成上面的验证码,我们就可以使用snoopy(比curl要轻量,所以我喜欢)来模拟浏览器器,访问网站了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-360025-1-1.html 上篇帖子: Php设计模式:行为型模式(三) 下篇帖子: php超级功能,汉字转拼音
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表