验证码识别与自动灌水(http://blog.csdn.net/deadcat/archive/2007/02/15) -程序员宅基地

技术标签: Debian  其他资料  Linux  .net  Bash  Blog  

近来,一个朋友请我帮他在某个网站投票。投票程序设立了验证码,并且限制每个IP每天只能投一票。我是在debian sarge 3.1下面通过ADSL拨号上网的,IP限制可以通过重新拨号轻松搞定。网上有人说使用代理也可以,但是我找了很久,发现网上列出的大部分代理服务器都已 经无法访问。好了,下面的问题主要就是识别验证码和自动投票了。

网上有很多关于验证码识别的方法和思路,不过大部分都是在windows下面运行的。在linux下面有一个很有名的图片处理软件叫imagemagick。这个软件支持非常多的图片格式已经更多的图片处理方法,请看这里的图片效果:

我 的思路是,首先找到含有验证码的图片,把背景、杂色、条纹等干扰因素去掉,并把图片转化为黑白象素,以便于处理。然后分析图片上每个文字的位置,精确的把 整个图片分割成包含每个文字的小图片。我关注的这个投票网站上的验证码是有0到9这十个数字构成了,我就用GIMP——是的,GIMP是linux下面不 可多得的图像处理软件——打开验证码图片,把十个数字一一截取下来,并且分别命名为0.jpg到9.jpg。截取的时候一定要注意,每个文字最好留一点边 框,并且在截取后的小图片上要居中,这样更利于排除干扰,提高识别率。为了提高准确率,我把用GIMP把验证码放大到1600倍以后对每个象素进行处理。 等要识别图片上验证码的时候,使用相同的位置截取图片上的文字,然后和刚才保存的十个小图片一一对比,与之差异最小的那个图片的序号就是该位置上的文字 了。ImageMagick在命令行下面运行,支持MAE,MSE,PSE,PSNR,RMSE等多种比较方式。根据图片中干扰的情况,选择一种最合适的 方式,或者用多种方式逐步处理以后进行比较,验证码就可以轻松识别了。 放大1600倍获取准确位置

至于识别验证码后进行自动灌水就很简单了。linux下面有一个更强大的工具curl,它可以通过HTTP,FTP,HTTPS等多种方式访问远程服务器,自动上传或下载数据。首先用curl查看其HTTP头信息

* About to connect() to xxxx.com port 80
* Trying xxx.xxx.xxx.xxx... * connected
* Connected to xxxx.com (xxx.xxx.xxx.xxx) port 80
> GET / HTTP/1.1
User-Agent: curl/7.13.1 (debian-linux-gnu) libcurl/7.13.1 OpenSSL/0.9.7e zlib/1.2.2.2 libidn/0.5.13
Host: xxxx.com
Pragma: no-cache
Accept: */*

< HTTP/1.1 302 Moved Temporarily
< Via: 1.1 PROXY
< Connection: Keep-Alive
< Proxy-Connection: Keep-Alive
< Transfer-Encoding: chunked
< Date: Tue, 04 Jul 2006 05:55:16 GMT
< Location: http://xxxx.com/queryVote.do?type=netvotes&Group=1
< Content-Type: text/html;charset=gb2312
< Server: WebLogic Server 8.1 SP2 Fri Dec 5 15:01:51 PST 2003 316284
< Set-Cookie: JSESSIONID=EqCEDyCC2JGex2sLoT231l6NP38OStZaFf9zLSHUxb2MxrqLBE1i!1559900188; path=/

java 代码
  1. <html></html>22  <head></head>23  "Content-Type" content="text/html; charset=gb2312">24  25  26  "#FFFFFF">27  ...28  29  3031    


32 * Connection #0 to host xxxx.com left intact
33 * Closing connection #0
34
从第19行中可以看出,改站点使用了JSESSION这个cookie。查看投票页面的源代码,我发现投票时使用了POST方法,有五个表单项目需要提交。我把这些都记录下来,构成一个POST字符串就可以了。

上面所说的很罗嗦,还是看我写的代码吧(源网址被改成了xxxx.com)





parse

=
=
convert .jpeg -crop 9x13++ -a.jpeg
convert .jpeg -crop 9x13++ -b.jpeg
convert .jpeg -crop 9x13++ -c.jpeg
convert .jpeg -crop 9x13++ -d.jpeg
pic a,b,c,d

=
=
num ,,,,,,,,

=
=

=
=


=

-fr -abcd.jpeg




=
iii++

pon dsl-provider /dev/null curl.log

curl \
cookie \
\
\
http://xxxx.com/MakeEXPWD code.jpeg
=
curl \
cookie \
\
\
\
\
\
\
http://xxxx.com/VoteForm.jsp?= \
\
http://xxxx.com/vote.

=



-fr code.jpeg
poff dsl-provider /dev/null curl.log





代码中第三行表示把整个程序的输出重定向到文件,可以用于无人值守的批量运行时。如果程序中有很多输入,这样做就可以不必逐一对每个输出的重定向了。
下 面是parse函数,用于对获取到的图片进行识别。分析时,首先截取图片的预定区域,并与准备好的小图片逐一比较,取参数中的最值,其对应的小图片就是该 位置的文字了。比较时使用到了浮点运算,这是bash的弱势所在,所以要用bc进行高精度计算。比较两个图片所用的compare命令支持很复杂的参数和 诸如MAE,MSE,PSE,PSNR,RMSE等多种方式,这里只是用了其中一种。
函数之后就是程序的主循环部分。每次循环时都把adsl断线并重新拨号。从拨号成功到数据能够正常传输之间可能有一段延误时间,所以要sleep一会儿。
下面的第一个curl有两个作用:首先,它从目标网站获取含有验证码的图片;另外,它还取得了当前连接的cookie,并且初始化服务器端的session。其中的-j参数表示每次拨号都抛弃以前的cookie。
第 二个curl使用了刚才取得的cookie,使用post方法向目标站点提交投票数据。其中的name是投票人的姓名,投票程序规定相同的名字只能投一 票,所以我干脆把用时间来表示了。在投票以后的返回页面中检查“投票成功”四个字,如果有则表示本次投票已成功,计数器加一。第55行的$?就表示上一个 命令的返回值:找到关键词时返回0。
每次操作结束以后都要把临时文件删除,同时更新状态行。echo命令加上-n参数表示输出信息后不换行;再加上一个控制字符\r,可以不断更新当前的提示行,而不是一行一行的输出程序运行结果,这样看起来更简洁一些。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fengyouhua/article/details/83167057

智能推荐

Android学习:java.lang.ClassCastException: android.widget.ImageButton异常处理_java.lang.classcastexception: androidx.appcompat.w-程序员宅基地

文章浏览阅读3.4w次,点赞3次,收藏4次。在调程序时总是出现异常关闭的现象,log显示:03-26 07:58:09.528: E/AndroidRuntime(398): Caused by: java.lang.ClassCastException: android.widget.ImageButton折腾了我一下午,后来发现是同一个控件在XML中和JAVA文件中类型不一致导致的。无语死,亏我还一行一行的在JAVA文件里找错误_java.lang.classcastexception: androidx.appcompat.widget.appcompatimagebutton

【树形权限】树形列表权限互斥选择、el-tree设置禁用等等_element plus 中el-tree互斥-程序员宅基地

文章浏览阅读1.7k次。树形列表权限互斥选择、el-tree设置禁用等等_element plus 中el-tree互斥

DZone每日必读-News:2022 年 Java 开发:预测和选定趋势_java 有 aarch架构的版本吗-程序员宅基地

文章浏览阅读341次。去年很有趣——一个新的 LTS 版本,取得了一些惊人的成功,但也发现了一个全球漏洞。在本文中,我们将尝试猜测和预测该行业将如何面对新的挑战,以及哪些创新和发展对其影响最大。_java 有 aarch架构的版本吗

但为君故——浅谈非科班大一在校大学生选择编程的心路历程。_编程心路历程-程序员宅基地

文章浏览阅读278次,点赞10次,收藏2次。但为君故——浅谈非科班大一在校大学生选择编程的心路历程。_编程心路历程

IDEA-项目文件旁边出现0%classes,0% lines covered_idea模块中的0%是什么-程序员宅基地

文章浏览阅读1.7k次,点赞6次,收藏2次。本来想执行Debug的,不小心点成了下面的项目中的文件就带着0%classes,0% lines covered使用ctrl + ALT + F6弹出如下框,去掉勾选后点击Show Selected就可以去掉了..._idea模块中的0%是什么

从SpringFox向SpringDoc转移(OpenAPI2向OpenAPI3转移)_springfox 3.0 转换为 springdoc-openapi-程序员宅基地

文章浏览阅读3.9k次,点赞3次,收藏11次。转移原因在学习使用spring集成swagger3时查阅文档发现SpringFox未支持 OpenAPI3 标准,而是还在支持2017年就已经停止维护的OpenAPI2了而搜遍全网写OpenAPI3的教程少的可怜但还是找到了与之相关的文章文章跳转但没有关于权限验证的相关教程,答案还得去官网找官网链接转移步骤删除springfox和swagger 2依赖项。而是添加springdoc-openapi-ui依赖2.替换注解3.替换Docket添加OpenAPI类型的_springfox 3.0 转换为 springdoc-openapi

随便推点

java代码混淆 源代码保护 代码逻辑混淆 代码加密 支持JDK16-程序员宅基地

文章浏览阅读2.6k次。  java代码可以反编译,因此有时候要保护自己的知识产权还真得费点心思,一般来说有三个思路:  1、将class文件加密,这个是最安全的,但也费事儿,因为要重写classloader来解密class文件;  2、使用花指令,使得class文件不能反编译(利用反编译工具漏洞);安全性一般,还是有花指令破解器;  3、代码混淆,提高代码阅读成本;简单易操作,一般采用这种或者与其它方式结合;  我们项目中用到的即为代码混淆工具ProGuard,相关文章参考:https://blog.csdn

ValueError: Only know how to handle extensions: ['png']; with Pillow installed matplotlib can handle_only know how to handle extensions: [u'png']; with-程序员宅基地

文章浏览阅读1.8k次。只要安装Pillow库就可以解决了1.在命令行中找到对应虚拟环境位置,然后activate虚拟环境名进入虚拟环境2.安装Pillowconda install Pillow运行过程如下:安装成功,问题解决。..._only know how to handle extensions: [u'png']; with pillow installed matplotl

使用slmgr.vbs -rearm命令重置,提升需要提升特权 [此博文包含图片]_slmgr 重置-程序员宅基地

文章浏览阅读1.7w次。win7按照论方法,使用slmgr.vbs -rearm命令进行重置,但是系统提示“错误0xC004F025拒绝访问:所请求的操作需要提升特权”。出现问题图片见附件: 解决C:\Windows\System32下找到CMD.EXE文件,右键点击cmd.exe的图标,然后选择“以管理员身份运行”打开命令提示符,这样才能真正用使用管理员权限运行命令。_slmgr 重置

2024年Android面试笔试总结(Android精心整理篇)-程序员宅基地

文章浏览阅读236次,点赞4次,收藏9次。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。一个人可以走的很快,但一群人才能走的更远。

c++11的异步线程操作_c++异步线程-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏12次。一、异步线程无论是在哪种语言中,都会面临异步操作的问题。基本上异步操作的实现可以大致分为系统级和应用级(封装的库也算应用级)。系统级一般是通过中断或者线程实现,在应用层面上一般是通过线程来实现。异步操作的目的是为了提高响应的并发量和控制访问的安全性以及健壮性。说的再直白一些,就是把访问过程,处理过程和响应过程分离。异步是相对于同步来说,同步相当于一问一答,必须实现,假如你去银行办理业务,你问柜台的小姐姐一句话,半天才回复你,估计你就怒了。但是如果你去带着一些木料去定作家具,就不愿意等在那儿,而愿..._c++异步线程

MySQL安装教程(详细版)_mysql8.0.36安装教程-程序员宅基地

文章浏览阅读1.6w次,点赞77次,收藏228次。MySQL免费安装教程、如何验证MySQL是否安装成功?怎么关掉MySQL服务?MySQL 端口问题如何解决?MySQL如何开机自启OR手动自启?安装MySQL时Starting the server 安装失败怎么解决?_mysql8.0.36安装教程

推荐文章

热门文章

相关标签