作者:曾立 Email:
[email protected]
说明:
建立验证码模板库,自动获取并破解JPEG格式网站验证码的例子,可实现网站的机械式查询、登录等功能。
下载地址:
1.仅源代码(前端页面和后台匹配算法,约200K) 下载
2.简化运行版(不含Tomcat和Java运行时环境,约11M) 下载
3.全部打包(含Tomcat和Java运行时环境,约30M) 下载
打包清单:(共包括4个目录,2个文件):
1.jdk1.4目录: java运行环境
2.tomcat5.0目录:Web服务器
3.MyIE目录:带弹出窗口过滤插件的IE浏览器
4.dll目录:动态链接库,需复制到系统目录c:/winnt/system32或c:/windows/system32中
5.ImageMagick-6.2.5-4-Q16-windows-dll.exe: JPEG解码库,必须安装
6.Jmagick.jar:验证码破解过程中需要调用的Jar包,需要复制到c:/jdk1.4/jre/lib/ext路径
运行步骤:
1.解开压缩包package.rar,例如至package目录
2.分别复制Package/jdk1.4目录和Package/tomcat5.0目录到c盘根目录下
3.右键打开“我的电脑”->属性->高级->环境变量
在用户变量里面点击“新建”按钮,新建两个用户变量
变量名:JAVA_HOME 变量值:c:/jdk1.4
变量名:CLASSPATH 变量值:.;c:/jdk1.4/lib/dt.jar;c:/jdk1.4/lib/tools.jar
(注意上面的变量值不要漏了前面的. 否则会出错)
变量名:TOMCAT_HOME 变量值:c:/tomcat5.0
最后点击确定退出
4. 将库文件Package/jmagick.jar复制到c:/jdk1.4/jre/lib/ext目录下
5. 双击ImageMagick-6.2.5-4-Q16-windows-dll.exe,并按默认安装路径和设置安装JPEG解码库。
6. 将Package/dll目录下的所有动态链接库文件复制系统目录C:/winnt/system32下,如为XP操作系统,则相应为c:/windows/system32目录
7. 如 果你目前登录的用户名不是Administrator,则需要修改xlcx.jsp里面的一个路径,即将administrator改为你当前登录的用户 名称,如dodo。首先进入c:/tomcat5.0/webapps/hpjx目录,右键打开xlcx.jsp,选择“打开方式”->“记事本 ”。
8. 进入c:/tomcat5.0/bin目录,双击startup.bat,启动TOMCAT服务器
9.双击Package/MyIE目录下MyIE.exe,启动MyIE浏览器
10. 打开MyIE浏览器的“选项”->广告猎手->编辑过滤列表,将以下网址进行过滤
http://www.chs*.com.cn/util/msg.jsp 该页面的弹出表示查询结果为空,即查无此人,所以需要借助MyIE的广告猎手将其屏蔽过滤。然后点击“确定”按钮退出设置。请确认“广告猎手”->“使用弹出窗口过滤”一栏被选中对勾
11. 在MyIE地址栏里面输入http://localhost/xlcx.jsp,将看到以下页面:
12. 选择高校名次、办学类型、毕业年份、培养层次,初始查询编号,要翻阅的人数,学生姓名,点击“开始”按钮即可开始查询。注意:
a.只能查询2005年毕业的学历证书信息
b.初始编号即你要查询的起始编号,前面补0,只能填写6位
c.查阅人数一次不要太多,最好不要超过5000,具体情况据机器配置和网络带宽定
d.学生姓名可输也可留空,但为了避免返回的查询量过大,建议输入姓
e.再以下的几栏由系统自动生成,勿需修改
13. 查询结果示例:
14.注意:每次打开MyIE浏览器进行查询之前,建议先清空Internet临时文件以及c:/tomcat5.0/webapps/hpjx/temp目录。
- package gxhpjx;
-
- import java.awt.Dimension;
- import java.awt.Rectangle;
- import magick.ImageInfo;
- import magick.MagickImage;
- import magick.MagickException;
- import magick.QuantizeInfo;
- import magick.ColorspaceType;
- import magick.MagickApiException;
- import magick.PixelPacket;
- import magick.DrawInfo;
- import magick.ResolutionType;
- import magick.ProfileInfo;
- import magick.MontageInfo;
- import magick.Magick;
- import magick.MagickInfo;
-
- import java.io.File;
- import java.io.IOException;
- import java.io.FileOutputStream;
- import java.net.URI;
-
- import java.util.Calendar;
- import javax.imageio.*;
- import java.net.URL;
- import java.awt.image.*;
-
- /**
- * For decoding the verification codes at the website http://www.chsi.com.cn
- * Only for your reference and please do NOT use it for any illegal or
- * commerce activity.
- *
- * @author Dodo [email protected] Dec 14,2005
- */
-
- public class VerifiDecoder {
-
- private final int pixel_diff = 50000; //象素差 default to 50000
- private final int class_threshold = 70;//分类阈值 default to 70
- private final int code_length = 4; //验证码长度 default to 4
-
- /*
- * Param1: String templatePath 模板库路径
- * Param2: String inputPath 输入路径
- * Param3: String inputFileName 输入文件名称
- * Param4: int code[] 存储匹配结果
- *
- * return: true if and only if decoding is successful, false otherwise.
- */
- public boolean decode(String templatePath,String inputPath,String inputFileName,int code[]){
- try {
- System.out.println("输入路径为:"+inputPath + inputFileName);
- ImageInfo inputInfo = new ImageInfo(inputPath + inputFileName);
-
- //切分坐标系
- Rectangle rect[] = { new Rectangle(1, 1, 20, 17),new Rectangle(20, 1, 20, 17),
- new Rectangle(38, 1, 15, 17), new Rectangle(54, 1, 15, 17)
- };
-
- PixelPacket templetPPacket = null; //切分后的模板象素包
- PixelPacket inputPPacket = null; //切分后的待匹配象素包
-
- Calendar startTime = Calendar.getInstance();//计时
- int m = 1;
- for(; m<=code_length; m++){
-
- MagickImage inputImage = new MagickImage(inputInfo);
- inputImage = inputImage.cropImage(rect[m-1]);//切分待匹配矩形
-
- for (int n=0; n<=9; n++){
- String templateFileName = m + "_" + n + ".jpg";//模板图片文件
- ImageInfo templetInfo = new ImageInfo(templatePath + templateFileName);
-
- MagickImage templetImage = new MagickImage(templetInfo);
- templetImage = templetImage.cropImage(rect[m-1]);//切分模板矩形
-
- int i,j=0,k=0;
- for (i=1; i <= 59; i++) {
- for (j=1; j<=14; j++) {//default to i<=59 j<=14
- templetPPacket = templetImage.getOnePixel(i,j);//获取模板x,y象素包
- inputPPacket = inputImage.getOnePixel(i,j);
-
- if (Math.abs(templetPPacket.getRed()-inputPPacket.getRed())>=pixel_diff
- & Math.abs(templetPPacket.getGreen()-inputPPacket.getGreen())>=pixel_diff
- & Math.abs(templetPPacket.getBlue()-inputPPacket.getBlue())>=pixel_diff
- ){
- k++;//统计相异象素包
- }
- }
- }
- if (k < class_threshold) {//匹配成功
- code[m-1] = n;//存储匹配结果
- System.out.println("模板文件:"+templatePath+templateFileName + "/n待匹配文件:"+inputPath+inputFileName);
- System.out.println("行:i=" + i + " 列:j=" + j + " 相异点个数:k=" + k);
- System.out.println("模板第" + m + "位: " + n + " 输入:" + n + "/n");
- break;//跳出循环,取消该位上的匹配
- }
- }
- }
- Calendar endTime = Calendar.getInstance();//计时
- System.out.print("/n验证码识别结果:");
- if (m>code_length){
- for (int i=0; i<code_length; i++){
- System.out.print(code[i]);
- }
- System.out.print(" [成功] ");
- System.out.println(" 用时:"+ (endTime.getTimeInMillis() - startTime.getTimeInMillis()) + " 毫秒/n");
- return true;
- }else {
- System.out.println(" [失败] /n");
- }
- }
- catch (MagickApiException ex) {
- System.err.println("MagickException: " + ex + ": " + ex.getReason()
- + ", " + ex.getDescription());
- ex.printStackTrace();
- }
- catch (MagickException ex) {
- System.err.println("MagickException: " + ex);
- ex.printStackTrace();
- }
- return false;
- }
-
- /*
- * 提供Facade方法封装decoding过程
- *
- * */
-
- public String facade(String templatePath, String inputPath, String inputFileName, URL url)throws Exception{
-
- int code[] = {0,0,0,0}; //匹配结果
- BufferedImage image = ImageIO.read(url);
- ImageIO.write(image,"JPEG",new File(inputPath+inputFileName));//从网站上读取输入验证码,保存至本地
-
- VerifiDecoder vd = new VerifiDecoder();
- vd.decode(templatePath,inputPath,inputFileName,code);
-
- String res = "";
- for (int i = 0; i<code.length; i++){
- res = res + code[i];
- }
- return res;
- }
-
- /**
- * 重载facade方法,直接访问本地已获取的验证码图片
- *
- * */
-
- public String facade(String templatePath, String inputPath, String inputFileName)throws Exception{
-
- int code[] = {0,0,0,0}; //匹配结果
-
- VerifiDecoder vd = new VerifiDecoder();
- vd.decode(templatePath,inputPath,inputFileName,code);
-
- String res = "";
- for (int i = 0; i<code.length; i++){
- res = res + code[i];
- }
- return res;
- }
-
- /*
- * 查找Base目录下及其下一级子目录下的特定文件
- *
- * Param1: String baseDir 根目录
- * Param2: String fileInCache 要在缓冲中查找的目标文件名匹配关键字
- * Param3: String newPathFile 转移后的目标文件名及路径
- * return: String[] 由于IE缓存目录Contend.IE5目录下的几个目录是随机生成的,所以
- * 需要搜寻验证码所在的某个子目录,并把该子目录及图片名称以字符串数组形式返回
- * */
- public String[] findFile(String baseDir, String fileInCache, String newPathFile){
- String[] res = {"",""};
- try{
- File file = new File(baseDir);
- File inputFile = new File(newPathFile);
- if (file.exists()) {
- int i,k = 1;
- //while (k<=1){//轮循直到要查找的文件在IE缓存中出现
- System.out.print("*");
- for (i = 0; i< file.list().length; i++){
- int j;
- if (file.listFiles()[i].isDirectory()){ //子目录
- //System.out.println("查询目录:"+file.listFiles()[i]);
- for (j = 0; j < file.listFiles()[i].list().length; j++){
- File subfile = file.listFiles()[i].listFiles()[j];//子子目录
- if (subfile.isFile()&& subfile.getName().startsWith(fileInCache)){
- res[0] = subfile.getParent().substring(subfile.getParent().lastIndexOf("//")+1);
- res[1] = subfile.getName();//缓冲中的文件名
- System.out.println("/n===== OK! 找到第[" + k + "]张 "+ subfile.getName()+" 位于:"+ res[0] + " ===== ");
- if (inputFile.exists()){
- if (!inputFile.delete())
- System.out.println("目标目录中的旧图片删除失败!");
- }
- if (subfile.renameTo(inputFile))//转移缓存中的所有验证图片
- System.out.println("转移成功!/n");
- else System.out.println("转移失败!/n");
- k++;
- }
- }
- }
- //}
- }
- }
- }
- catch(Exception e){
- e.printStackTrace();
- }
- return res;
- }
-
- public static void main(String[] args) throws Exception{
-
- String templatePath = "D://trash//template//";
- String inputPath = templatePath;
- String inputFileName = "ValidatorIMG.jpg";//待匹配图片文件:ValidatorIMG
- int code[] = {0,0,0,0}; //匹配结果
-
- URL url = new URL("http://www.chsi.com.cn/ValidatorIMG.JPG?ID=" + Math.random()*10000);
- BufferedImage image = ImageIO.read(url);
- ImageIO.write(image,"JPEG",new File(templatePath+inputFileName));//从网站上读取输入验证码,保存至本地
-
- VerifiDecoder vd = new VerifiDecoder();
- vd.decode(templatePath,inputPath,inputFileName,code);
- }
- }