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

作者:曾立  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目录。


  1. package gxhpjx;

  2. import java.awt.Dimension;
  3. import java.awt.Rectangle;
  4. import magick.ImageInfo;
  5. import magick.MagickImage;
  6. import magick.MagickException;
  7. import magick.QuantizeInfo;
  8. import magick.ColorspaceType;
  9. import magick.MagickApiException;
  10. import magick.PixelPacket;
  11. import magick.DrawInfo;
  12. import magick.ResolutionType;
  13. import magick.ProfileInfo;
  14. import magick.MontageInfo;
  15. import magick.Magick;
  16. import magick.MagickInfo;

  17. import java.io.File;
  18. import java.io.IOException;
  19. import java.io.FileOutputStream;
  20. import java.net.URI;

  21. import java.util.Calendar;
  22. import javax.imageio.*;
  23. import java.net.URL;
  24. import java.awt.image.*;

  25. /** 
  26.  * For decoding the verification codes at the website http://www.chsi.com.cn 
  27.  * Only for your reference and please do NOT use it for any illegal or 
  28.  * commerce activity.
  29.  *   
  30.  * @author Dodo  [email protected]  Dec 14,2005
  31.  */

  32. public class VerifiDecoder {
  33.     
  34.     private final int pixel_diff = 50000;   //象素差 default to 50000
  35.     private final int class_threshold = 70;//分类阈值 default to 70
  36.     private final int code_length = 4;      //验证码长度 default to 4
  37.     
  38.     /*
  39.      * Param1: String templatePath 模板库路径
  40.      * Param2: String inputPath 输入路径
  41.      * Param3: String inputFileName 输入文件名称
  42.      * Param4: int code[] 存储匹配结果
  43.      * 
  44.      * return: true if and only if decoding is successful, false otherwise.
  45.      */
  46.     public boolean decode(String templatePath,String inputPath,String inputFileName,int code[]){
  47.            try {                  
  48.             System.out.println("输入路径为:"+inputPath + inputFileName);
  49.                ImageInfo inputInfo = new ImageInfo(inputPath + inputFileName);            
  50.                         
  51.             //切分坐标系            
  52.             Rectangle rect[] = { new Rectangle(1, 1, 20, 17),new Rectangle(20, 1, 20, 17),
  53.                                  new Rectangle(38, 1, 15, 17), new Rectangle(54, 1, 15, 17)
  54.                                 };

  55.             PixelPacket templetPPacket = null//切分后的模板象素包
  56.             PixelPacket inputPPacket = null//切分后的待匹配象素包            
  57.             
  58.             Calendar startTime = Calendar.getInstance();//计时
  59.             int m = 1;
  60.             for(; m<=code_length; m++){
  61.                 
  62.                 MagickImage inputImage = new MagickImage(inputInfo);
  63.                 inputImage = inputImage.cropImage(rect[m-1]);//切分待匹配矩形
  64.                 
  65.                 for (int n=0; n<=9; n++){
  66.                     String templateFileName = m + "_" + n + ".jpg";//模板图片文件
  67.                     ImageInfo templetInfo = new ImageInfo(templatePath + templateFileName);                   
  68.                     
  69.                     MagickImage templetImage = new MagickImage(templetInfo);
  70.                     templetImage = templetImage.cropImage(rect[m-1]);//切分模板矩形
  71.                     
  72.                     int i,j=0,k=0;            
  73.                     for (i=1; i <= 59; i++) {
  74.                         for (j=1; j<=14; j++) {//default to i<=59 j<=14
  75.                             templetPPacket = templetImage.getOnePixel(i,j);//获取模板x,y象素包
  76.                             inputPPacket = inputImage.getOnePixel(i,j);
  77.                             
  78.                             if (Math.abs(templetPPacket.getRed()-inputPPacket.getRed())>=pixel_diff
  79.                                     & Math.abs(templetPPacket.getGreen()-inputPPacket.getGreen())>=pixel_diff
  80.                                     & Math.abs(templetPPacket.getBlue()-inputPPacket.getBlue())>=pixel_diff    
  81.                             ){
  82.                                 k++;//统计相异象素包                            
  83.                             }                    
  84.                         }
  85.                     }
  86.                     if (k < class_threshold) {//匹配成功
  87.                         code[m-1] = n;//存储匹配结果
  88.                         System.out.println("模板文件:"+templatePath+templateFileName + "/n待匹配文件:"+inputPath+inputFileName);        
  89.                         System.out.println("行:i=" + i + "    列:j=" + j + "    相异点个数:k=" + k);
  90.                         System.out.println("模板第" + m + "位: " + n + "   输入:" + n + "/n");                                
  91.                         break;//跳出循环,取消该位上的匹配
  92.                     }
  93.                 }                    
  94.             }
  95.             Calendar endTime = Calendar.getInstance();//计时
  96.             System.out.print("/n验证码识别结果:");
  97.             if (m>code_length){                
  98.                 for (int i=0; i<code_length; i++){
  99.                     System.out.print(code[i]);
  100.                 }
  101.                 System.out.print(" [成功] ");
  102.                 System.out.println("  用时:"+ (endTime.getTimeInMillis() - startTime.getTimeInMillis()) + " 毫秒/n");
  103.                 return true;
  104.             }else {                 
  105.                 System.out.println(" [失败] /n");                
  106.             }   
  107.         }
  108.         catch (MagickApiException ex) {
  109.             System.err.println("MagickException: " + ex + ": " + ex.getReason()
  110.                     + ", " + ex.getDescription());
  111.             ex.printStackTrace();
  112.         }
  113.         catch (MagickException ex) {
  114.             System.err.println("MagickException: " + ex);
  115.             ex.printStackTrace();
  116.         }
  117.         return false;
  118.     }
  119.     
  120.     /*
  121.      * 提供Facade方法封装decoding过程
  122.      * 
  123.      * */
  124.     
  125.     public String facade(String templatePath, String inputPath, String inputFileName, URL url)throws Exception{
  126.         
  127.         int code[] = {0,0,0,0}; //匹配结果                
  128.         BufferedImage image = ImageIO.read(url);
  129.         ImageIO.write(image,"JPEG",new File(inputPath+inputFileName));//从网站上读取输入验证码,保存至本地
  130.         
  131.         VerifiDecoder vd = new VerifiDecoder();
  132.         vd.decode(templatePath,inputPath,inputFileName,code);
  133.         
  134.         String res = "";
  135.         for (int i = 0; i<code.length; i++){
  136.             res = res + code[i];
  137.         }
  138.         return res;
  139.     }
  140.     
  141.     /**
  142.      * 重载facade方法,直接访问本地已获取的验证码图片
  143.      *  
  144.      * */
  145.     
  146.     public String facade(String templatePath, String inputPath, String inputFileName)throws Exception{
  147.         
  148.         int code[] = {0,0,0,0}; //匹配结果                
  149.         
  150.         VerifiDecoder vd = new VerifiDecoder();
  151.         vd.decode(templatePath,inputPath,inputFileName,code);
  152.         
  153.         String res = "";
  154.         for (int i = 0; i<code.length; i++){
  155.             res = res + code[i];
  156.         }
  157.         return res;
  158.     }
  159.     
  160.     /*
  161.      * 查找Base目录下及其下一级子目录下的特定文件
  162.      * 
  163.      * Param1: String baseDir 根目录
  164.      * Param2: String fileInCache 要在缓冲中查找的目标文件名匹配关键字     
  165.      * Param3: String newPathFile 转移后的目标文件名及路径
  166.      * return: String[] 由于IE缓存目录Contend.IE5目录下的几个目录是随机生成的,所以
  167.      *         需要搜寻验证码所在的某个子目录,并把该子目录及图片名称以字符串数组形式返回      
  168.      * */
  169.     public String[] findFile(String baseDir, String fileInCache, String newPathFile){
  170.         String[] res = {"",""};
  171.         try{            
  172.             File file = new File(baseDir);
  173.             File inputFile = new File(newPathFile);
  174.             if (file.exists()) {
  175.                 int i,k = 1;
  176.                 //while (k<=1){//轮循直到要查找的文件在IE缓存中出现
  177.                     System.out.print("*");
  178.                     for (i = 0; i< file.list().length; i++){
  179.                         int j;
  180.                         if (file.listFiles()[i].isDirectory()){    //子目录                
  181.                             //System.out.println("查询目录:"+file.listFiles()[i]);                        
  182.                             for (j = 0; j < file.listFiles()[i].list().length; j++){
  183.                                 File subfile = file.listFiles()[i].listFiles()[j];//子子目录
  184.                                 if (subfile.isFile()&& subfile.getName().startsWith(fileInCache)){
  185.                                     res[0] = subfile.getParent().substring(subfile.getParent().lastIndexOf("//")+1);
  186.                                     res[1] = subfile.getName();//缓冲中的文件名
  187.                                     System.out.println("/n===== OK! 找到第[" + k + "]张  "+ subfile.getName()+"  位于:"+ res[0] + " ===== ");
  188.                                     if (inputFile.exists()){
  189.                                         if (!inputFile.delete())
  190.                                             System.out.println("目标目录中的旧图片删除失败!");
  191.                                     }
  192.                                     if (subfile.renameTo(inputFile))//转移缓存中的所有验证图片
  193.                                         System.out.println("转移成功!/n");
  194.                                     else System.out.println("转移失败!/n");
  195.                                     k++;
  196.                                 }                                
  197.                             }                            
  198.                         }
  199.                     //}                    
  200.                 }                
  201.             }            
  202.         }
  203.           catch(Exception e){
  204.               e.printStackTrace();
  205.          }
  206.         return res;
  207.     }
  208.     
  209.     public static void main(String[] args) throws Exception{   

  210.         String templatePath = "D://trash//template//";
  211.         String inputPath = templatePath;
  212.         String inputFileName = "ValidatorIMG.jpg";//待匹配图片文件:ValidatorIMG
  213.         int code[] = {0,0,0,0}; //匹配结果

  214.         URL url = new URL("http://www.chsi.com.cn/ValidatorIMG.JPG?ID=" + Math.random()*10000);        
  215.         BufferedImage image = ImageIO.read(url);
  216.         ImageIO.write(image,"JPEG",new File(templatePath+inputFileName));//从网站上读取输入验证码,保存至本地
  217.         
  218.         VerifiDecoder vd = new VerifiDecoder();
  219.         vd.decode(templatePath,inputPath,inputFileName,code);
  220.     }
  221. }

你可能感兴趣的:(java,tomcat,浏览器,String,image,web服务)