如何使用PHP对网站验证码进行破解


Posted in PHP onSeptember 17, 2015

验证码的功能一般是防止使用程序恶意注册、暴力破解或批量发帖而设置的。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。学习验证码的破解/识别技术,不仅可以知道验证码的原理,而且可以让你知道怎样才能防止验证码被破解。

最常见的验证码主要有以下几种:

1、四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。
2、随机数字图片验证码。图片上的字符比较中规中矩,有的可能加入一些随机干扰素,还有一些是随机字符颜色,验证作用比上一个好。没有基本图形图像学知识的人,不可破!
3、各种图片格式的随机数字+随机大写英文字母+随机干扰像素+随机位置。
4、汉字是注册目前最新的验证码,随机生成,打起来更难了,影响用户体验,所以,一般应用的比较少。
为简单起见,破解说明主要针对是第2种类型的,先来看看网上常见的这种验证码的图片:

如何使用PHP对网站验证码进行破解

  • 第一种,最容易,图片背景和数字都使用相同的颜色,字符规整,字符位置统一。
  • 第二种,看似不容易,其实仔细研究会发现其规则,背景色和干扰素无论怎么变化,验证字符字符规整,颜色相同,所以排除干扰素非常容易,只要是非字符色素全部排除即可。
  • 第三种,看似更复杂,处理上面提到背景色和干扰素一直变化外,验证字符的颜色也在变化,并且各个字符的颜色也各不相同。
  • 第四种,除了第三个图片上提到的特征外,又在文字上加了两条直线干扰率,看似困难其实,很容易去掉。

验证码识别一般分为以下几个步骤:

1、取出字模 识别验证码,毕竟不是专业的OCR识别,并且,由于各个网站的验证码各不相同,所以,最常见的方法就是就是建立这个验证码的特征码库。去字模时,我们需要多下载几张图片,使这些图片中,包括所有的字符,我们这里的字母只有图片,所以,只要收集到包括0-9的图片即可。
2、二值化 二值化就是把图片上的验证数字上每个象素用一种数字表示1,其他部分用0表示。这样就可以计算出每个数字字模,记录下这些字模来,当作key即可。
3、计算特征 把要识别的图片,进行二值化,得到图片特征。
4、对照样本 把步骤3种的图片特征码和验证码的字模进行对比,得到验证图片上的数字。
使用目前这种方法,对验证码的识别基本上可以做到100%。

通过以上步骤,您可能说了,并没有发现如何取出干扰素啊!其实取出干扰素的方法很简单,干扰素的一个重要特征是,不能影响验证码的显示效果,所以制作干扰素时它的RGB可能低于或者高于某个特定值,比如我给的例子中的图片,干扰素的RGB各项值是不会超过125的,所以,这样我们就很容易去掉干扰素了。

简单的验证码只有数字和字母组成,格式统一,每次出现位置固定。下面继续深入研究识别验证码,这次需要识别的目标是:验证码有字符和数字组成,验证码存在旋转(可能左右都旋转),位置不固定,存在字符与字符之间的粘连,且验证码有更强的干扰素。

我们以下图为例进行讲解。

如何使用PHP对网站验证码进行破解

第一步:二值化。把验证码的部分用 1 表示,背景部分用 0 表示出来,识别方法很简单,我们打印出验证码整张图片的 RGB ,然后分析其规律即可,通过 RGB 码,我们很容易分辨出上面这张图片的 R 值大于 120 , G 和 B 的值小于 80 ,所以依据这个规则我们很容易把上面的图片二值化。

再来看看上面的第三种验证码图片

如何使用PHP对网站验证码进行破解

刚看上去,感觉很复杂。验证码的图片每次背景色都不相同,且不是单色,各个验证码数字的颜色每次也各不相同。貌似很难二值化,其实我们打印出其 RGB 值很容易就发现。无论验证数字颜色如何变化,该数字的 RGB 值总有一个值小于 125 ,所以通过如下判断 $rgbarray['red'] < 125 || $rgbarray['green']<125|| $rgbarray['blue'] < 125 我们就很容易分辨出哪里是数字,哪里是背景。

我们能够找到这些规律的原因是,在制作验证码的干扰素时,为了使干扰素不影响数字的显示效果,必须使用干扰素的 RGB 和数字 RGB 相互独立,互不干扰。只要懂得这个规律,我们就很容易实现二值化。

我们找到的 120 , 80 , 125 等阈值,可能和实际的 RGB 有出入,所以,有时二值化后,会有部分地方出现 1 ,对于验证码上固定位置显示数字,这种干扰没有太大意义。但是对于验证码位置不确定的图片来说,在我们切割字符时,很可能造成干扰。所以,在二值化后要进行去噪处理。

第二步:去噪处理。去噪的原理很简单,就是把孤立的有效的值去掉,如果噪点比较高,要求的效率也比较高的话,这里面也有很多工作要做。幸好这里我们不要求这么高深,我们使用最简单的方法就可以,如果一个点为 1 则判断这个点的上下左右上左上右下左下右 8 个方位上数字是否为 1 ,如果不为 1 ,就认为是一个燥点,直接设置为 1 即可。

如何使用PHP对网站验证码进行破解

如上图所示,我们使用此方法很容易发现红色方框部分的 1 为燥点,直接设置为 1 即可。在判断时我们使用了一个技巧,有时候的噪点可能是两个连续的 1 ,所以我们计算这个点的 8 个方向上的值之和,最后我们判断他们的和是否小于特定的阈值。

第三步:切割字符。切割字符的方法有很多种,这里采用最简单的一种,先垂直方向切割成为字符,然后在水平方向去掉多于的 0000 ,如下图

如何使用PHP对网站验证码进行破解

第一步切割红线部分,第二步切割蓝线部分,这样就可以得到独立的字符了。但是像下面这种情况

如何使用PHP对网站验证码进行破解

按上面的方法会把 dw 字符切割成一个字符,这是错误的切割,所以这里我们涉及到粘连字符的切割。

第四步:粘连字符切割。制作验证码时,规则字符的粘连很容易分割开,如果字符本身有缩放,变形就很难处理,经过分析,我们可以发现,上面的字符粘连属于很简单的方式,只是规则字符的粘连,所以处理这种情况,我们也使用很简单的处理方式。当完成分割操作后,我们不能马上确定分割的部分就为一个字符,要进行验证,验证的关键因素就是,切割下来的字符的宽是否大于阈值,这个阈值的取舍标准是,一个字符无论怎么旋转变形都不会大于这个阈值,所以,如果我们切割的块大于这个阈值,就可以认为这是一个粘连字符;如果大于两个阈值之和,就认为是三个字符粘连,以此类推。知道这个规则后,切割粘连字符也就很简单了。如果我们发现是粘连字符块,直接平分这个块为两个或者多个新的块就可以。当然为了更好的还原字符,我一般都采用平分 +1 , -1 对字符块的部分进行适当的补充。

第五步:匹配字符。对于旋转字符的特征码建立,有很多种方法,这里就不做深入研究了。我这里使用的最简单的方式,为所有字符的所有情况建立匹配库,所以在我提供的代码种增加了 study 操作,其目的就是,先有人手工识别图片的验证码,然后通过 study 方法,写入特征码库。这样写入的图片数据越多,验证识别的准确行也就越高。

经过以上步骤,我们基本上可以识别现在互联网上大部分的验证码,这里我们都是使用的最简单的方法,没有使用任何 OCR 知识。

另外制作验证码的一些建议:

对于识别验证码的程序来说,最难得部分是验证字符的切割和特征码的建立,而国内很多程序员只做验证码时,总是喜欢在验证码加很多干扰素,干扰线,影响效果不说,还达不到很好的效果;所以,要想使自己验证码难于本识别,只做下面两点就够了

1、字符粘连,最好所有的字符都有粘连的部分;
2、不要使用规格字符,验证码的各个部分使用不同比例的缩放或者旋转。
只要做到这两点,或者这两点的变形,识别程序就很难识别。

以上就是本文的全部内容:使用PHP对网站验证码进行破解,希望对大家的学习有所帮助。

PHP 相关文章推荐
消息持续发送的完整例子
Oct 09 PHP
.htaccess文件保护实例讲解
Feb 06 PHP
执行、获取远程代码返回:file_get_contents 超时处理的问题详解
Jun 25 PHP
Youku 视频绝对地址获取的方法详解
Jun 26 PHP
PHP大转盘中奖概率算法实例
Oct 21 PHP
PHP基于工厂模式实现的计算器实例
Jul 16 PHP
DEDE实现转跳属性文档在模板上调用出转跳地址
Nov 04 PHP
thinkPHP批量删除的实现方法分析
Nov 09 PHP
实例解析php的数据类型
Oct 24 PHP
PHP中str_split()函数的用法讲解
Apr 11 PHP
TP3.2.3框架文件上传操作实例详解
Jan 23 PHP
ThinkPHP 5 AJAX跨域请求头设置实现过程解析
Oct 28 PHP
浅谈php+phpStorm+xdebug配置方法
Sep 17 #PHP
PHP 9 大缓存技术总结
Sep 17 #PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
Sep 14 #PHP
php生成静态html页面的方法(2种方法)
Sep 14 #PHP
PHP概率计算函数汇总
Sep 13 #PHP
整理php防注入和XSS攻击通用过滤
Sep 13 #PHP
教你识别简单的免查杀PHP后门
Sep 13 #PHP
You might like
不用GD库生成当前时间的PNG格式图象的程序
2006/10/09 PHP
mysql 中InnoDB和MyISAM的区别分析小结
2008/04/15 PHP
PHP中的函数嵌套层数限制分析
2011/06/13 PHP
基于JQuery的多标签实现代码
2012/09/19 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
jQuery实现等比例缩放大图片让大图片自适应页面布局
2013/10/16 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
2013/10/22 Javascript
javascript教程之不完整的继承(js原型链)
2014/01/13 Javascript
Javascript基础教程之while语句
2015/01/18 Javascript
jquery实现上下左右滑动的方法
2015/02/09 Javascript
jQuery Ajax调用WCF服务详细教程
2015/03/31 Javascript
深入理解Ajax的get和post请求
2016/06/02 Javascript
Bootstrap对话框使用实例讲解
2016/09/24 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
2017/02/18 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
浅谈webpack组织模块的原理
2018/03/10 Javascript
使用vuex存储用户信息到localStorage的实例
2019/11/11 Javascript
JavaScript写个贪吃蛇小游戏(超详细)
2020/03/17 Javascript
wxpython 学习笔记 第一天
2009/03/16 Python
Python抓取Discuz!用户名脚本代码
2013/12/30 Python
用Python代码来绘制彭罗斯点阵的教程
2015/04/03 Python
python使用matplotlib绘图时图例显示问题的解决
2017/04/27 Python
python中正则表达式 re.findall 用法
2018/10/23 Python
对python插入数据库和生成插入sql的示例讲解
2018/11/14 Python
selenium在执行phantomjs的API并获取执行结果的方法
2018/12/17 Python
numpy:np.newaxis 实现将行向量转换成列向量
2019/11/30 Python
Python加密模块的hashlib,hmac模块使用解析
2020/01/02 Python
Django CSRF认证的几种解决方案
2020/03/03 Python
美国本地交易和折扣网站:LocalFlavor.com
2017/10/26 全球购物
机电一体化专业应届本科生求职信
2013/09/27 职场文书
安全教育心得体会
2013/12/29 职场文书
四群教育工作实施方案
2014/03/26 职场文书
工商局局长个人对照检查材料思想汇报
2014/09/23 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
病人写给医生的感谢信
2015/01/23 职场文书
《孙子兵法》:欲成大事者,需读懂这些致胜策略
2019/08/23 职场文书