需验证码识别,对常用论坛的验证码识别的时候大家用来做群发是最合适不过了。一个非常有意义的参考

注:非crazycoder原装,文章是转载的,原文出处不祥了,很多地方都有,找不到原出处了

验证码(captcha)是伴随自动提交程序(spam)的出现而出现的。现在各种论坛、博客、投票等程序都带有验证码功能。大部分验证码都比较容 易识别,只需要简单对照一下特征码就可以得到百分之百准确的结果。也有稍微复杂一点的,比如phpwind和discuz的验证码。

前段时间做了phpwind和discuz的验证码识别,phpwind6.0以前的验证码和discuz最新的验证码如果在不改变后台验证码配置的情况下,识别正确率几乎可以达到100%,现在跟大家分享一下识别方法。

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

  1. 取出字模
  2. 二值化
  3. 计算特征
  4. 对照样本

各种验证码在具体的步骤上操作会有所不同。

我的程序是用VC++写的,这里不贴详细代码了,只讲识别方法。

先说phpwind验证码的识别方法:

具体分为这几步:

  1. 把图片横向等宽分为4块
  2. 找出每块图片中分布最多的一种颜色
  3. 与已有样本比较得出结果

因为这个验证码的字符分布几乎是等宽的,所以我们首先把图片切为4份,这样方便取出每一个字符。分成4块后,通过每一块中的颜色值对比可以很快得到 字符的特征。因为每一块中字符的颜色值比杂点颜色值要多很多,而且字符是纯色的,所以只要统计出最多的一种颜色,然后去除其它颜色就可以得到只有字符的干 净图片。然后对图片二值化(即构造一个二维数组对应图片上有颜色的点,把有颜色的点的数组值置为1,无颜色的置为0),与样本比对即可得到字符。当然首先 要得到样本。样本的制作与上面分析的步骤一致。经过测试,上面这种方法的识别率是100%的,不会有差错。

discuz的验证码识别较之phpwind要稍难一点。因为图片带有不太容易去掉的背景。字符也不是单纯的字符,有阴影边框,而且不等宽,位置不确定。我们具体分为以下几步:

  1. 去除背景色
  2. 分出每一个字符区域
  3. 用轮廓法(berg)得到特征码
  4. 与样本比较得出结果

这个背景色是渐变的而字符的颜色是不变的。首先去除对角线上找不到相同颜色的点,然后统计出每一种颜色占用的区域的宽度和高度。去除占用区域高度小 于图片总高度1/5或大于图片总高度2/3的点,因为一个字符不可能达到这种尺寸。再去除密度(即颜色点数/颜色所占的区域宽高的积)小于15%的点。剩 下的就只有干净的字符的颜色点了。

把这些点分为4份。(分割的办法为从左到右用一条竖直的线扫描,扫描线经过的连续区域就是字符区域。)分成4个字符块后,我们就可以对每一个字符块进行轮廓特征取值。

什么是轮廓法?我是由berg(berg是网易社区的牛人,对我帮助不少)那里获知验证码识别中的轮廓法。即将一个字模点阵,以四条直线由上下左右 4个方向向字符中心扫描,遇到点即停下,把每一条线通过的路径长度记下。然后以比路径长度和其它一些相关的参数得到正确的字符。

我稍微变换了一下轮廓法。即把4个方向上的路径长度变为波的形式。波峰记为1,波谷记为0,最后得到一个由1和0组成的特征串,与样本串比较即可得 到匹配结果。有几个字符,如V和Y、H和M、4和6等,得到的特征串可能是一样的,这样需要通过其它的一些参数来辅助得到结果。

下面是我计算的特征串和字符的对照样本:
10-10-10-10- X 
1-1010-1-10101- W 
-1010--- W 
1--1-101- T 
-1-1010-10- R 
--10-10- R 
101-101-1010-1010- Q 
-1-101-1- P 
--1-1- P 
-10--1010- M 
-10-10-10- K 
10-10-1-1- J 
10-10--- J 
101-101-1010-10- G 
--101-1- F 
--1010-- E 
101-101-10101-101- C 
101-10-10-10- C 
-1-10101-1- B 
---- B 
10101-101-101-101- 9 
1---10- 9 
-101--- 8 
10--1-101- 7 
-1-10-- 6 
1-101-10-101- 4 
1010---- 3 
1010-101-1010-- 2 
10--10-- 2 
//below is equivocal
1-10-1-101- V /Y
10-10-10-- G /Q
-10--10- H /M
10101-101-10101-101- 3 /8
101-101-101-101- 4 /6

上面这种方法,对discuz的默认验证码,即如图所示的验证码识别正确率为100%

上面对phpwind和discuz的验证码识别方法均没有用到高级的算法,更加没有用到人工智能的知识,不免有点遗憾,不过准确率相当高,也容易看懂。

在实际应用中可能遇到一些问题,比如discuz验证码可以在后台设为gif图片格式。如何把gif动画中那一个字符帧转为bmp图片呢?下面是VC里面的方法:

BOOL CCaptchaBreak::Gif2Bmp(CString &sPath)
{
 ULONG_PTR   GdippToken;   
 GdiplusStartupInput   GdippStart;   
 GdiplusStartup(&GdippToken,&GdippStart,0);
 BSTR bsTemp = sPath.AllocSysString();
 Bitmap   bmp(bsTemp);
 ::SysFreeString(bsTemp);

int   FrameCount,FramePos,size,pause;   
 PropertyItem*   pPropItem;   
 GUID   pageGuid;   
 GUID*   pDimID;   
 UINT   count;

count=bmp.GetFrameDimensionsCount();

pDimID=new GUID[count];

bmp.GetFrameDimensionsList(pDimID,count);   
 FrameCount=bmp.GetFrameCount(&pDimID[0]);

if (1==FrameCount)/if is bmp then exit
 {
  delete[]pDimID;   
  return FALSE;
 }

size=bmp.GetPropertyItemSize(PropertyTagFrameDelay);   
 pPropItem=(PropertyItem*)malloc(size);

bmp.GetPropertyItem(PropertyTagFrameDelay,size,pPropItem);   
 delete[]pDimID;

pageGuid=FrameDimensionTime;   
 FramePos=0;

int iFontFramePos = 0;
 int iMaxPause = 0;
 while (FramePos

return TRUE;
}

BOOL CCaptchaBreak::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
 UINT  num = 0;         / number of image encoders
 UINT  size = 0;        / size of the image encoder array in bytes

ImageCodecInfo* pImageCodecInfo = NULL;

GetImageEncodersSize(&num, &size);
 if(size == 0)
  return FALSE;

pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
 if(pImageCodecInfo == NULL)
  return FALSE;

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)
 {
  if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
  {
   *pClsid = pImageCodecInfo[j].Clsid;
   free(pImageCodecInfo);
   return TRUE; / Success
  }    
 }

free(pImageCodecInfo);
 return FALSE;  
}

【转载】http://www.51yzm.com/InfoShow.asp?id=64

最新Discuz验证码和PhpWind验证码的识别相关推荐

  1. Python爬虫教程:验证码的爬取和识别详解

    今天要给大家介绍的是验证码的爬取和识别,不过只涉及到最简单的图形验证码,也是现在比较常见的一种类型. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里 ...

  2. Python爬虫基础:验证码的爬取和识别详解

    今天要给大家介绍的是验证码的爬取和识别,不过只涉及到最简单的图形验证码,也是现在比较常见的一种类型. 运行平台:Windows Python版本:Python3.6 IDE: Sublime Text ...

  3. python 识别登陆验证码图片(完整代码)_python 识别登录验证码图片功能的实现代码(完整代码)...

    在编写自动化测试用例的时候,每次登录都需要输入验证码,后来想把让python自己识别图片里的验证码,不需要自己手动登陆,所以查了一下识别功能怎么实现,做一下笔记. 首选导入一些用到的库,re.Imag ...

  4. left join 一对多只取一条_Python爬虫教程:验证码的爬取和识别详解

    目前,很多网站会采取各种各样的措施来反爬虫,验证码就是其中一种,比如当检测到访问频率过高时会弹出验证码让你输入,确认访问网站的不是机器人.但随着爬虫技术的发展,验证码的花样也越来越多,从最开始简单的几 ...

  5. python识别中文验证码_Python实现验证码识别

    大致介绍 在python爬虫爬取某些网站的验证码的时候可能会遇到验证码识别的问题,现在的验证码大多分为四类: 1.计算验证码 2.滑块验证码 3.识图验证码 4.语音验证码 这篇博客主要写的就是识图验 ...

  6. 2022最新whatsapp接收不到验证码解决方法

    2022最新whatsapp接收不到验证码解决方法 以下内容是背景,可直接跳过,正文从第二段开始 最近因为有了一个新手机卡,所以就想好好利用一下,把全套的SNS社媒都弄一下,包括Facebook, L ...

  7. 基于PaddlePaddle2.0验证码端到端的识别

    验证码端到端的识别,是对<我的PaddlePaddle学习之路>笔记六--验证码端到端的识别 的升级,这篇文章是我18年初写的,基于当时的V2版本编写,现在有点过时了,突然想升级一下. 在 ...

  8. nodejs识别验证码,图片验证码

    最近做自动化遇到验证码的问题,之前识别字母和数字验证码都是使用tesseract.js,识别率都不错,中文也可以识别不过识别率不高. 我自己平常使用识别验证码的方式主要有三种, 一种是上面说的tess ...

  9. 转:nodejs识别验证码,图片验证码

    最近做自动化遇到验证码的问题,之前识别字母和数字验证码都是使用tesseract.js,识别率都不错,中文也可以识别不过识别率不高. 我自己平常使用识别验证码的方式主要有三种: 一种是上面说的tess ...

最新文章

  1. html及js试题,HTML+css+js试题..docx
  2. scrapy接selenium关键步骤
  3. android瓦片地图下载,Andorid 如何加载 瓦片地图
  4. Ticket 服务: 一种经济的分布式唯一主键生成方案
  5. SqlDataAdapter的使用注意事项
  6. boost::hana::monadic_fold_right用法的测试程序
  7. 【2018.3.31】模拟赛之一-ssl2406 约数【水题】
  8. 程序员35岁前需要完成的10件事
  9. 安卓工控主板运行时会自动重启_工控机日常维护的方法与步骤
  10. 【通达信指标公式】多空分时幅图指标,股票期货T+0经典分时指标
  11. C#webservice实例
  12. Java实现 LeetCode 707 设计链表(环形链表)
  13. 简单欧拉公式c语言算法,算法之_欧拉公式
  14. PPT的默认设置以及快捷键的使用(超级实用的PPT操作)
  15. 推荐一个易学预测、学术研讨、资源分享网站:龙腾易学网
  16. 赛事相关 | 你好,微信大数据挑战赛,我是TI-ONE
  17. 阿里云服务器和虚拟主机之间的区别
  18. 分布式存储系统Kudu(一)、核心原理
  19. JSF——JSF 标签
  20. matlab 双均线,我的双级别双重均线系统的建立初探

热门文章

  1. User Interaction Design
  2. 2017-9-5-Java 泛型
  3. Oracle SQL 优化原则(实用篇)
  4. js中常用framesetiframe页面跳转传参方法实例大全
  5. 设计模式之strategy模式(C++实现)
  6. fscokopen 中执行超时 使用stream_set_timeout设置超时
  7. Linux vgchange 命令
  8. Linux之at命令
  9. 系列TCP/IP协议-ARP与RARP
  10. 使用HttpClient 发送 GET、POST、PUT、Delete请求及文件上传