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

作者:曾立  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; iSystem.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; ilength; 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; ilength; 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);     } }

你可能感兴趣的:(技术空间)