[Java] 识别图片验证码
现在大多数网站都采用了验证码来防止暴力破解或恶意提交。但验证码真的就很安全吗?真的就不能被机器识别??
我先讲讲我是怎么实现站外提交留言到一个网站的程序。
这个网站的留言版大致如下:

我一看这种简单的4位数字验证码,马上就感觉到有戏了。直觉告诉我让电脑来识别这些图片验证码据对简单o(∩_∩)o...
首先我马上在这个页面用右键菜单看源代码

知道验证码获取页面后 你可以直接用 http://www.XXXX.com/imgchk/validatecode.asp
这样去访问你会发现你打开的就是一个验证码图片。

对的其实返回的就是图片文件的2进制流而已。接着先用右键保存一张验证码的图片。因为要开始分析这张图片了,什么用什么工具?PhotoShop????不用就一般的画图工具就可以了。我们要搞清楚的是这几个数字分别占几个像素就可以了。

可以看出 一个数字5*9
| 也就是45个像素。恩 这就可以了 另外我们可以看出默认区域就是白色 (姑且说是白色因为我们肉眼看就是白色) 那么我的程序识别原理就是固定去扫描这45个像素点。看每个点的颜色是不是和默认的颜色一致 一致的话就标记为0 ,不一致就标记为1 。 如一个数子是2 那么我的程序扫描出来的图像就应该是: 011110 100001 000001 000001 000010 000100 001000 010000 100000 111111 如果一个数字是7那么扫描出来的图像就是: 111111 100001 000010 000010 000100 000100 001000 001000 010000 010000 恩,就这么简单呵呵。下面给出图像 扫描的java类 (不好意思,在我会的语言里面除开java就剩sql了) package com.util; //~--- JDK imports ------------------------------------------------------------ import com.sun.image.codec.jpeg.JPEGCodec; import java.awt.*; import java.io.*; import java.net.*; import javax.imageio.*; public class ImgIdent { // 数字字符比特表 private final long[][] NUMERIC = { }, // '0' }, // '1' }, // '2' }, // '3' }, // '4' }, // '5' }, // '6' }, // '7' }, // '8' } }; // '9' // 字框高 // 字框横向间隙 // 字框纵向间隙 // 字框宽 private int IntImgHeight; private BufferedImage img; private int intBgColor; private int intCharColor; private int intImgWith; private int intMaxX; private int intMaxY; private int intMinX; private int intMinY; // 座标原点 private String strNum; public ImgIdent(BufferedImage img) throws IOException { this.img = img; init(); } public ImgIdent(File file) throws IOException { img = ImageIO.read(file); init(); } public ImgIdent(URL url) throws IOException { img = ImageIO.read(url); init(); } private void init() { // 得到图象的长度和宽度 IntImgHeight = img.getHeight(); // 得到图象的背景颜色 // System.out.println(intBgColor); // 初始化图象原点座标 } private void getBaseInfo() { System.out.println(intBgColor + "|" + intCharColor); System.out.println(intMinX + "|" + intMinY + "|" + intMaxX + "|" + intMaxY); } private Point[] getCharRange(int intNo) { // 左上右下点座标 Point pBottomRight ); // 左上点 pTopLeft.y = pOrigin.y; // 右下点 pBottomRight.y ; return new Point[] { pTopLeft, pBottomRight }; } private char getBit(int x, int y) { int intCurtColor; intCurtColor = img.getRGB(x, y); //System.out.println("[" + x + "," + y + "]" + intCurtColor + "==" + intBgColor + "==>" + (Math.abs(intCurtColor) >7308252)); ' : '; // 5689325 6008535 private String getCharString(int intNo) { // 本字符的左上右下点座标 Point pTopLeft ]; Point pBottomRight ]; // 换算边界值 intX1 = pTopLeft.x; intY1 = pTopLeft.y; intX2 = pBottomRight.x; intY2 = pBottomRight.y; // System.out.println("intX1=" + intX1); // 在边界内循环取象素 String strChar = ""; for (i = intY1; i <= intY2; i++) { for (j = intX1; j <= intX2; j++) { System.out.print(getBit(j, i)); strChar = strChar + getBit(j, i); } System.out.println(); } System.out.println(); return strChar; } public int getNum(int intNo) { // 取得位字符串 // System.out.println(intNo+"=="+strChar); // 取得串高位串和低位串 String strCharLow ); // 计算高位和低位值 System.out.println(lCharHigh); ); System.out.println(lCharLow); // 在数字中循环比较 ; i++) { ])) { intNum = i; break; } else { )) { intNum ; } // 834533329 242870177 else { intNum ; } // 默认为1 低位为 937393609 937393601 } return intNum; } public String getValidatecode(int length) { String strNum = ""; ; i <= length; i++) { synchronized (this) { strNum += String.valueOf(getNum(i)); } } return strNum; } public void saveJPEG(BufferedImage iag, String savePath) throws FileNotFoundException, IOException { OutputStream jos = new FileOutputStream(savePath); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(jos); JPEGEncodeParam jpegEP = JPEGCodec.getDefaultJPEGEncodeParam(iag); jpegEP.setQuality((, true); encoder.encode(iag, jpegEP); jos.flush(); jos.close(); } } 恩这样数字是可以识别出来了,可以我要怎么完成提交那块的工作呢?好在Apache已经为我做完了。我用了 package com.util;
//~--- non-JDK imports -------------------------------------------------------- import org.apache.commons.httpclient.*; //~--- JDK imports ------------------------------------------------------------ import java.awt.image.BufferedImage; import java.io.InputStream; import javax.imageio.ImageIO; public class MyHttpClient { public synchronized void doSomeThing(String title, String name, String Content, String proIP, int port, boolean usePro) { // 构造HttpClient的实例 HttpClientParams clientParams = new HttpClientParams(); // 隐藏自己请求相关的信息 // httpClient.getHttpConnectionManager().getParams().setSoTimeout(30 * 1000); HttpState httpState = new HttpState(); httpClient.setParams(clientParams); httpClient.getParams().setParameter(HttpClientParams.HTTP_CONTENT_CHARSET, "GBK"); httpClient.setState(httpState); clientParams.setVersion(HttpVersion.HTTP_1_1); // httpClient.getHostConfiguration().setProxy("148.233.159.58", 3128); if (usePro) // 使用代理 { httpClient.getHostConfiguration().setProxy(proIP, port); } // 创建GET方法的实例 // 使用系统提供的默认的恢复策略 try { // 执行getMethod // System.out.println(statusCode); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + getMethod.getStatusLine()); } // 读取内容 InputStream inStream = getMethod.getResponseBodyAsStream(); // 处理内容 // System.out.println(new String(responseBody)); ImgIdent imgIdent = new ImgIdent(iag); // imgIdent.saveJPEG(iag, "C:/ddd.jpg"); System.out.println(validate); PostMethod method = new PostMethod("http://www.XXX.com/Guestbook/add_msg.asp"); String connect = Content; String Title = title; method.setParameter("subject", Title); method.setParameter("g_name", name); method.setParameter("companyname", ""); method.setParameter("mail", ""); method.setParameter("homepageurl", "http://"); method.setParameter("pic", "p5.gif"); method.setParameter("validatecode", validate); method.setParameter("content", connect); // if (todo) { // String Stringresponse = new String(method.getResponseBodyAsString().getBytes("8859_1")); // 打印返回的信息 // System.out.println(Stringresponse); method.releaseConnection(); // System.out.println(iag.getHeight()); } catch (Exception e) { // 发生网络异常 } finally {} // 释放连接 getMethod.releaseConnection(); } } } 恩 就这样了,最后结合SAF整成这样了。什么?为什么不用SWT?想过了SWING才是王道o(∩_∩)o... |
[Java] 识别图片验证码的更多相关文章
- 【java+selenium3】Tesseract-OCR识别图片验证码 (十六)
[java+selenium+Tesseract-OCR(图片识别)+AutoIt(windows窗口识别)]完成自动化图片验证码识别! 一.AutoIt(windows窗口识别)参考:https:/ ...
- python 识别图片验证码报IOError
说一下困扰了我一周的问题:识别图片验证码 本来我按照安装步骤(http://www.cnblogs.com/yeayee/p/4955506.html?utm_source=tuicool&u ...
- 用Java实现图片验证码功能
一.什么是图片验证码? 可以参考下面这张图: 我们在一些网站注册的时候,经常需要填写以上图片的信息. 1.图片生成实体类: package com.hexianwei.graphic; import ...
- python爬虫20 | 小帅b教你如何使用python识别图片验证码
当你在爬取某些网站的时候 对于你的一些频繁请求 对方会阻碍你 常见的方式就是使用验证码 验证码的主要功能 就是区分你是人还是鬼(机器人) 人 想法设法的搞一些手段来对付技术 而 技术又能对付人们的想法 ...
- java实现图片验证码
一.验证码生成类 package hbi.tech.utils; import javax.imageio.ImageIO; import java.awt.*; import java.awt.im ...
- 使用burp插件captcha-killer识别图片验证码
0x01 开发背景 说起对存在验证码的登录表单进行爆破,大部分人都会想到PKav HTTP Fuzzer,这款工具在前些年确实给我们带来了不少便利.反观burp一直没有一个高度自定义通杀大部分图片验证 ...
- Java 生产图片验证码
import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;impor ...
- 识别图片验证码的三种方式(scrapy模拟登陆豆瓣网)
1.通过肉眼识别,然后输入到input里面 from PIL import image Image request.urlretrieve(url,'image') #下载验证码图片 image = ...
- 【转】Python OCR识别图片验证码
转载自:博客 对于某些网站登录的时候,往往需要输入验证码才能实现登录.如果要爬虫这类网站,往往总会比这个验证码导致无法爬取数据.以下介绍一种比较折中的方法,也是比较可行的方法: 实现思想: 1.通过截 ...
随机推荐
- scala 连接 mysql
code: import java.sql.{ResultSet, DriverManager} import com.mysql.jdbc.Connection object hoursAvg { ...
- HLS -- m3u8档案格式解析
1. Playlist file 一个M3U的 Playlist 就是一个由多个独立行组成的文本文件,每行由回车/换行区分.每一行可以是一个URI.空白行或 是以”#“号开头的字符串,并且空格只能存在 ...
- 设计模式知识搜集(c++)
理解设计模式有两种途径,一种是看UML类图,一种是看代码理解实例,UML(一个简单的介绍)看懂了对理解设计模式大有裨益,代码容易陷进去,因此最好能找到适当且易于理解的应用场景,这下面实际上每个都是我收 ...
- ASP.NET 应用程序生命周期概述[转自MSDN]
本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段. 阶段 ...
- mac机器下远程仓库添加完毕之后,却无法上传应有的内容。
Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you ha ...
- LINQ标准查询操作符(二)——Join、GroupJoin、GroupBy、Concat、
四.联接操作符 联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作.这两个数据源对象通过一个共同的值或者属性进行关联. LINQ有两个联接操作符:Join和GroupJoin. 1. J ...
- xcode报错:Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
今天使用xcode编译工程发现一个问题,这里记录一下防止忘记 xcode报错: Command /Applications/Xcode.app/Contents/Developer/Toolchain ...
- 让CSS3给你的文字加上边框宽度,并实现镂空效果
这次,我主要向大家介绍一下CSS3下的-webkit-text-stroke属性,并分享几个用该属性制作的镂空文字效果. 1.-webkit-text-stroke属性简介 CSS边框的一个不足就是只 ...
- HD2046骨牌铺方格
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- C++11之sizeof
[C++11之sizeof] 在标准C++,sizeof可以作用在对象以及类别上.但是不能够做以下的事: 这会传回OtherType的大小.C++03并不允许这样做,所以会引发编译错误.C++11将会 ...
