一个自动识别网站验证码的程序例子

作者:曾立  Email:zengl@ics.ict.ac.cn   

说明:
建立验证码模板库,自动获取并破解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  zengl@ics.ict.ac.cn  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);
    •     }
    • }
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页