本文 51386 pv

14

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

© kekehu / 技术资源 / 2009.10.19 / 18:29 / 51386PV

以下内容转载自网络。

在上篇文章[php实现验证码的识别(初级篇)]中,讲了如何识别简单的验证,这里的简单指的是验证码有数字和字母组成,格式统一,每次出现位置固定。

这篇文章将继续深入研究识别验证码,这次识别的目标是,验证码有字符和数字组成,验证码存在旋转(可能左右都旋转),位置不固定,存在字符与字符之间的粘连,且验证码有更强的干扰素。这篇文章讲解的方法,并不是万能的解决方案,并且提供代码不能直接解决你的问题,这里仅仅是方法,具体需求得有读者自己解决,需要说明的是,识别验证码与具体的编程语言无关,这里只是使用php语言实现,使用这里介绍的方法,你可以使用任何语言实现。

这篇文章逐步讲解识别验证码过程中的各个步骤。

如下图,随后的讲解我们都围绕此图展开。
点击在新窗口中浏览此图片

第一:二值化。
把验证码的部分用1表示,背景部分用0表示出来,识别方法很简单,我们打印出验证码整张图片的RGB,然后分析其规律即可,通过RGB码,我们很容易分辨出上面这张图片的R值大于120,G和B的值小于80,所以依据这个规则我们很容易把上面的图片二值化。再看初级篇中提到的两张图点击在新窗口中浏览此图片点击在新窗口中浏览此图片,刚看上去,感觉很复杂。验证码的图片每次背景色都不相同,且不是单色,各个验证码数字的颜色每次也各不相同。貌似很难二值化,其实我们打印出其RGB值很容易就发现。无论验证数字颜色如何变化,该数字的RGB值总有一个值小于125,所以通过如下判断

if($rgbarray['red'] < 125 || $rgbarray['green']<125|| $rgbarray['blue'] < 125)
{
    那么验证码的部分用1表示
}

这样我们就很容易分辨出哪里是数字,哪里是背景。

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

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

第二:去噪。
出燥的原理很简单,就是把孤立的有效的值去掉,如果噪点比较高,要求的效率也比较高的话,这里面也有很多工作要做。幸好这里我们不要求这么高深,我们使用最简单的方法就可以,如果一个点为1则判断这个点的上下、左右、上左、上右、下左、下右、8个方位上数字是否为1,如果不为1,就认为是一个燥点,直接设置为0即可
点击在新窗口中浏览此图片
如上图所示,我们使用此方法很容易发现红色方框部分的1为燥点,直接设置为0即可。

在判断时我们使用了一个技巧,有时候的噪点可能是两个连续的1,所以php代码判断如下:
$num = 0;
if($data[$i][$j] == 1)
{
  // 上
  if(isset($data[$i-1][$j])){
    $num = $num + $data[$i-1][$j];
  }
  // 下
  if(isset($data[$i+1][$j])){
    $num = $num + $data[$i+1][$j];
  }
  // 左
  if(isset($data[$i][$j-1])){
    $num = $num + $data[$i][$j-1];
  }
  // 右
  if(isset($data[$i][$j+1])){
    $num = $num + $data[$i][$j+1];
  }
  // 上左
  if(isset($data[$i-1][$j-1])){
    $num = $num + $data[$i-1][$j-1];
  }
  // 上右
  if(isset($data[$i-1][$j+1])){
    $num = $num + $data[$i-1][$j+1];
  }
  // 下左
  if(isset($data[$i+1][$j-1])){
    $num = $num + $data[$i+1][$j-1];
  }
  // 下右
  if(isset($data[$i+1][$j+1])){
    $num = $num + $data[$i+1][$j+1];
  }
}
if($num == 0){
  $data[$i][$j] = 0;
}

上面的代码是计算这个点的8个方向上的值之和,最后我们判断他们的和是否小于特定的阈值。

第三:切割字符
切割字符的方法有很多种,这里我采用最简单的一种,先垂直方向切割成为字符,然后在水平方向去掉多余的0000,如下图:
点击在新窗口中浏览此图片
第一步切割红线部分,第二步切割蓝线部分,这样就可以得到独立的字符了。
但是像下面这种情况:
点击在新窗口中浏览此图片
按上面的方法会把dw字符切割成一个字符,这是错误的切割,所以这里我们涉及到粘连字符的切割。

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

提示:代码当中只考虑到两字粘连字符切割,如果是两个以上的字符粘连,请修改代码支持两个以上的字符粘连切割。

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

好了,经过以上步骤,我们基本上可以识别现在互联网上大部分的验证码,这里我们都是使用的最简单的方法,没有使用任何OCR知识。这些方法,应该属于非OCR领域的顶峰了,要想识别更加复杂的验证码,那就需要更多的OCR知识了。有机会的话,我会在高级篇中一一做介绍。

下面是一些容易识别的验证码,希望引起网站管理者的重视。
点击在新窗口中浏览此图片

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

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

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

我们看看,yahoo和google的验证码就知道,白字黑底,却很难被识别。
Google:点击在新窗口中浏览此图片
yahoo:点击在新窗口中浏览此图片

看不懂??不防看看php实现验证码的破解识别(初级篇):http://www.geekso.com/Valite/

以上php源文件下:
phpcrash.rar (已下载 8228 次)

演示地址:http://www.geekso.com/component/yanzhengma/

本文有 14 篇评论

  1. @ itzm Email 说 :
    2015.04.25 22:54
    avatar

    缺少文件 keys

  2. @ Emilio 说 :
    2015.01.10 13:45
    avatar

    smoke 没有验证码的库文件吗??另外,本网站的验证码真™容易破解

  3. @ 开心 Email 说 :
    2014.07.27 21:54
    avatar

    报错,不能用

  4. @ 嘿嘿 说 :
    2014.03.04 15:04
    avatar

    google和yahoo的验证码,人都没法识别anger

  5. @ aaa——aaa Email 说 :
    2013.11.09 11:24
    avatar

    这人故意不说的详细,留一手

  6. @ roam 说 :
    2013.04.26 11:50
    avatar

    没有keys文件啊

  7. @ cilun 说 :
    2013.04.21 14:25
    avatar

    请问如何获取到discuz验证码的地址??如果获取不到验证码的url地址,那就无法破解

  8. @ F UCK YOU 说 :
    2013.01.22 13:51
    avatar

    代码没通都往上整

  9. @ gKiwi 说 :
    2012.11.13 12:51
    avatar

    懂得思路了,谢了!回去写个java版本的!

  10. @ 木林森 Email 说 :
    2012.03.18 19:24
    avatar

    代码没有问题,不过似乎每次识别都自动study,不方便感觉

  11. @ junjun 说 :
    2012.03.08 06:43
    avatar

    代码有问题哦

  12. @ junguo.info Email 说 :
    2011.04.27 16:05
    avatar

    源代码有问题,参数还没有复制就初始化,肯定报错,博主可能是把源代码做了改正unhappy

  13. @ 叉烧 说 :
    2009.11.23 11:43
    avatar

    程序报错!“无法读取数据库文件设置数据库数据出错”

  14. @ 华晨 Email 说 :
    2009.10.27 19:57
    avatar

    天哪!这么厉害!验证码都被你破解了呀!shockzan

1/1 第一页 1 最后页

发表你的见解

打开HTML 打开UBB 打开表情 隐藏 记住我
emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot
emotemotemotemotemot