分享一个图片验证码识别的干货

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

最多见的验证码主要有如下几种:学习

  1. 四位数字,随机的一数字字符串,最原始的验证码,验证做用几乎为零。 
  2. 随机数字图片验证码。图片上的字符比较中规中矩,有的可能加入一些随机干扰素,还有一些是随机字符颜色,验证做用比上一个好。没有基本图形图像学知识的人,不可破!
  3. 各类图片格式的随机数字+随机大写英文字母+随机干扰像素+随机位置。 
  4. 汉字是注册目前最新的验证码,随机生成,打起来更难了,影响用户体验,因此,通常应用的比较少。 

为简单起见,破解说明主要针对是第2种类型的,先来看看网上常见的这种验证码的图片:网站

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

验证码识别通常分为如下几个步骤:图片

  1. 取出字模 识别验证码,毕竟不是专业的OCR识别,而且,因为各个网站的验证码各不相同,因此,最多见的方法就是就是创建这个验证码的特征码库。去字模时,咱们须要多下载几张图片,使这些图片中,包括全部的字符,咱们这里的字母只有图片,因此,只要收集到包括0-9的图片便可。
  2. 二值化 二值化就是把图片上的验证数字上每一个象素用一种数字表示1,其余部分用0表示。这样就能够计算出每一个数字字模,记录下这些字模来,看成key便可。
  3. 计算特征 把要识别的图片,进行二值化,获得图片特征。 
  4. 对照样本 把步骤3种的图片特征码和验证码的字模进行对比,获得验证图片上的数字。 

使用目前这种方法,对验证码的识别基本上能够作到100%。字符串

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

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

咱们如下图为例进行讲解。原理

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

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

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

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

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

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

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

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

第一步切割红线部分,第二步切割蓝线部分,这样就能够获得独立的字符了。可是像下面这种状况

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

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

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

通过以上步骤,咱们基本上能够识别如今互联网上大部分的验证码,这里咱们都是使用的最简单的方法,没有使用任何 OCR 知识。

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

对于识别验证码的程序来讲,最可贵部分是验证字符的切割和特征码的创建,而国内不少程序员只作验证码时,老是喜欢在验证码加不少干扰素,干扰线,影响效果不说,还达不到很好的效果;因此,要想使本身验证码难于本识别,只作下面两点就够了

  1. 字符粘连,最好全部的字符都有粘连的部分; 
  2. 不要使用规格字符,验证码的各个部分使用不一样比例的缩放或者旋转。 

只要作到这两点,或者这两点的变形,识别程序就很难识别。

相关文章
相关标签/搜索