九零登录

[【通过】] 一次很特别的验证码识别

[复制链接]
发表于 2016-3-30 19:35:28 | 显示全部楼层 |阅读模式
本帖最后由 小和尚 于 2016-3-30 21:29 编辑

一次很特别的验证码识别

简单验证码识别的步骤一般是去噪->切割->对比识别,一般来说这种工作特别费时间,所以遇到一些特别的站的时候就要多想想其他方式了。

最近想做一个APP,把学校的教务,一卡通,流量查询等各种系统集中在一起,但是遇到了一个严重的问题:门户系统的验证码。

教务,一卡通,流量都是需要通过门户进入的,当然我也可以选择将验证码返回到客户端让用户自己识别,然而我还是想尝试一下的。

验证码是如下的图片:

QQ截图20160330212718.jpg

这种验证码中间用了个扭曲的算法,将一部分图像扭曲了,如果直接识别,1和7的位置的不同会导致切割和识别出错,粗略计算了一下,如果按照这种方法,最终的识别率在百分之20左右,只能另寻生路。

其实,仔细看一下,这种验证码没有任何的随机噪点,然后对比一下第一排第二个验证码和第二排第二个验证码的最后一位数,两个“8”完全一模一样。

所以就可以考虑一下做个kv(key-value)映射表了。

经过大量的尝试,发现这些验证码里面只有1-9,所以一共有6561个验证码图片,而相同的验证码的图片也是一模一样的,所以这个kv映射表的key就是验证码图片的md5值,value就是验证码。

1、先来建立一个kv数据库,把所有的图片down下来,代码:

[Python] 纯文本查看 复制代码
<code>

#!/usr/bin python

#coding: utf-8

import requests

import MySQLdb

import md5

conn=MySQLdb.connect(host='localhost',user='root',passwd='',port=3306)

count = 9000

while count <= 50000:

   print count

   content = requests.get('图片地址.jpg').content

    m = md5.new()

   m.update(content)

    m = m.hexdigest()

   cur=conn.cursor()

   print m

   res = cur.execute("select md5 from md5.tables where md5='%s'"%m)

   print res

   if res == 0:

       cur.execute("insert into md5.tables(num, md5) values('%d','%s')" % (count, m))

       conn.commit()

       f = open('./data_2/' + str(count) + '.jpg', 'wb')

       f.write(content)

       f.close()

   count += 1

   cur.close()

conn.close()

</code>


2、然后就是需要识别6000多个图片,自己识别是很浪费时间的,所以我选择了一个打码平台,我使用的是云速:www点ysdm点net,6600个图片,当时他并没有开发文档,只有测试接口,要想识别,就只能从测试接口通过一个html-upload接口上传图片上去,这是代码,中间有用户名和密码等:

[Python] 纯文本查看 复制代码
<code>

#coding: utf-8

import requests

import re

import MySQLdb

conn=MySQLdb.connect(host='localhost',user='root',passwd='',port=3306)

for num in range(5222,6000):#0,6508

   cur=conn.cursor()

   try:

       cur.execute("select num from md5.tables order by num limit %d,1" %num)

       n = cur.fetchall()[0][0]

       print n,num

       files={'username':(None,''),

           'password':(None,''),

           'softid':(None,'1'),

           'timeout':(None,'60'),

           'softkey':(None,''),

           'typeid':(None,'5000'),

           'image':('%s.jpg'%n,open(r'E:\tmp\data_2\%s.jpg'%n,'rb').read(),'image/jpeg')

        }

       headers = {'Cookie':'_': 'zh-CN,zh;q=0.8', 'Accept-Encoding': 'gzip,deflate', 'Referer': 'http://www.ysdm.net/home/OnTest', 'DNT': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0', 'Origin': 'http://www.ysdm.net','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Cache-Control': 'max-age=0'}

       a = requests.post("http://www.ysdm.net/home/OnTest",files=files,headers=headers)

       code = re.search(':([1-9]{4})"',a.content).group(1)

   except Exception,e:

       print e

       code = '0000'

   print code

   cur.execute('update md5.tables set val=%s where num=%s' %(code, n))

   cur.close()

   conn.commit()

conn.close()

</code>


3、等了一天以后,百分之80的验证码就down下来了,不用过多,百分之80的识别率就OK了,因为不论怎样,百分之百的识别是不可能实现的。
这是最后的效果:

7.png
现在就是最后一步了,写个php来实现在线识别:

[PHP] 纯文本查看 复制代码
<code><?php

$mysqli = new mysqli('localhost','root','','md5');

if (mysqli_connect_errno()){

die('Unable to connect!'). mysqli_connect_error();

}

$mysqli->query("SET NAMES utf8");

$md5 = $_GET['md5'];

$md5_white = '';

if(!preg_match('([0-9a-f]{32})',$md5,$md5_white)) die("fuck");

$sql = "select val from tables where md5='$md5_white[0]'";

$query = $mysqli->query($sql);

while($rs=$query->fetch_array())

{

   if(!empty($rs['val'])) echo $rs['val'];

   else {

   echo "0";

    }

}

?></code>


这中间用了一些处理,只允许32位的md5传入,否则输出fu**。

最后访问http://localhost/md5.php?md5=xxxxx就可以返回验证码值了,客户端只需要将图片的md5值传过来就可以获取到验证码值。

评分

参与人数 1酒票 +5 收起 理由
管理05 + 5 欢迎加入90!

查看全部评分

发表于 2016-3-30 21:05:53 | 显示全部楼层
楼主,代码高亮下啊,这缩进都没。
 楼主| 发表于 2016-3-30 21:30:59 | 显示全部楼层
y0uki11 发表于 2016-3-30 21:05
楼主,代码高亮下啊,这缩进都没。

多谢!!之前没找到高亮!!
 楼主| 发表于 2016-3-30 21:42:04 | 显示全部楼层
请教@管理05 怎么修改邮箱!!我注册时候预留了QQ邮箱!一直收不到验证码!更改了好几遍邮箱,但是都不能成功!!
发表于 2016-3-30 21:54:15 | 显示全部楼层
小和尚 发表于 2016-3-30 21:42
请教@管理05 怎么修改邮箱!!我注册时候预留了QQ邮箱!一直收不到验证码!更改了好几遍邮箱,但是都不能成 ...

不建议使用QQ邮箱。如果实在无法接收,请联系我
发表于 2016-3-31 20:29:37 | 显示全部楼层
精彩 从验证码规律>>到打码平台识别》建立数据库》php在线识别 一气呵成~
发表于 2016-3-31 20:55:51 | 显示全部楼层
py+php都会的大神
发表于 2016-4-1 17:23:21 | 显示全部楼层
表哥做的东西不错呀 好像我们有些共同之处 介意留个联系方式 交流一下不

九零

GMT+8, 2026-10-22 12:52

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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