zoukankan      html  css  js  c++  java
  • 【原创】用C#.NET开发通用的验证码识别组件

    相信大家在开发过程中,基本都用到过验证码识别程序。一提到验证码识别,绝大多数兄弟想到的都是用C++的效率配上牛逼哄哄的二值化、边缘检测等算法来实现。但这种识别方式的依赖性太强,不可重用,无法扩展,假设对方稍微修改下验证码的变形算法(做过网站的都知道有多简单),可能你累死累活搞出来的识别程序就全部作废了。

     

    这里讲个我们公司的例子,为了识别支付宝登录的验证码,公司花大价钱请了一位牛人B用C++写了个支付宝验证码识别的DLL并做了导出,供我们在.NET平台下直接调用。当我们项目开发快结束的时候,这货竟然完全无法识别了!我们研究发现,是因为支付宝对文字做了简单的变形。牛人B则落井下石的告知需另付钱才能继续识别,因此老板就把这重任交给了我。

    作为热爱创造的苦逼程序猿,现在必须要拿出我们那渴望下班的热情,开始这漫漫的编码长路 ,首先提出我们的需求:

    1. 通用识别字母、数字、及混合验证码。

    2. 识别率必须要高(90%以上)。

    3. 识别速度要快(5秒内)。

    4. 支持异步及多线程并发识别。

    5. 调用简单,扩展性强。

    可能大家看到这需求时已经产生疑问了,怎么可能有通用的验证码识别程序?一套代码怎么可能识别所有网站的验证码?今天我们就通过第三方打码平台来解决这个变态的需求。现在听我慢慢道来,我们按面向对象的方式来确定这个组件中应该有的对象:

    • 打码平台(Platform)

    • 平台帐号(Account)

    • 识别策略(Strategy)

    • 验证码识别器(Decoder)

    首先,我们来说“打码平台(Platform)”,我们把验证码图片发送至打码平台,他们再通过大批量(24X7)在线的用户进行人工+机器识别,速度基本在1-5秒之间,完成后返回识别结果。现在来定义一个平台枚举集合,用作平台的随意切换:

    接着,我们来说“平台帐号(Account)”,每个平台都至少需要一个普通帐号和一个开发者帐号,普通帐号用作登录、充值、识别用。开发者帐号用作生成软件ID、软件KEY。很多兄弟一听到要充值就不敢往下看了,其实价格真的很便宜,1元钱可以识别250次(多么销魂的数字)。下边定义了平台帐号类,用作向策略类中传递帐号信息,这些信息在你注册普通帐号和开发者帐号后才可以获得:

    其次,我们再说“识别策略(Strategy)”,它主要封装与第三方平台的交互细节,为“验证码识别器”提供简单的操作方法,并支持识别策略的无限扩展(例如未来增加其他平台)。第一行定义了平台帐号信息字段;第二行定义了识别的具体方法,传入图片路径,并将验证码的识别结果返回为字符串。

    然后,我们来说“验证码识别器(Decoder)”,它主要用来封装识别细节,支持平台切换,提供给外部开发人员调用。第一行定义了Task异步识别方法,传入验证码图片路径,通过异步编程解决IO、网络操作耗时的问题;第二行至第四行定义了三个事件,分别在验证码识别的启动、完成、错误时触发。

     

    就这样,一个通用验证码识别组件就基本定义完成了,我知道你现在可能会说:#@¥@#¥#!@#!!这写的什么玩意?!但事实就是如此,从面向抽象的角度讲,确实已经完成了。只是我们还没有定对其进行实现,也就是说仅仅定义了规范,从应用上来讲并没有什么卵用。所以下边我们就来讲(IStrategy、IDecoder)这两个重要的接口如何实现。

    识别策略(Strategy)的实现:

     

    由上图得知,我们定义了一个若快平台的验证码识别策略来实现IStrategy接口。通过实现Recognize方法将帐号信息封装成字典随图片一起提交到第三方平台进行识别,并返回识别结果。同时我们还可以直接在构造函数中设置平台帐号。

    验证码识别器(Decoder)的实现:

    由上图得知,我们通过实现IDecoder的接口,利用反射获取运行时的策略,利用Task异步执行策略类中的Recognize方法,并在执行之前触发OnStart事件,执行之后触发OnCompleted事件,执行错误后触发OnError事件。同时获取到当前异步任务的线程ID及任务的执行时间并传递给事件。

    现在我们新建一个控制台程序来使用这个组件:

    下边我们同时识别三个验证码,大家可以看一下执行时间和准确率:

    本文验证码组件源代码、实例代码下载地址:https://github.com/coldicelion/Captcha-Recognizer

    到此为止,验证码识别组件就全部开发完毕了,喜欢的朋友请在Github上给星星。

  • 相关阅读:
    [转]OllyDBG 入门系列(一)-认识OllyDBG
    .net连接Sql时出现"已成功与服务器建立连接,但是在登录过程中发生错误。 (provider: TCP 提供程序, error: 0 指定的网络名不再可用。) "
    FCKeditor 2.0 的设置.修改.使用(转来的!)
    java中判断字符串是否数字的两种方法
    DATEDIFF 函数
    一个简单的数据库操作类
    Ajax多线程
    SQL Server应用程序中的高级SQL注入
    用ASP.NET开发三层架构【转载】
    下拉菜单选择头像
  • 原文地址:https://www.cnblogs.com/coldicelion/p/Captcha-Recognizer.html
Copyright © 2011-2022 走看看