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

来源:互联网 发布:时间悖论 知乎 编辑:程序博客网 时间:2024/06/06 22:00
作者:曾立  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目录。


  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  zengl@ics.ict.ac.cn  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. }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为诺娃2手机声音小怎么办 华为平板锁屏密码忘记了怎么办 华为麦芒6手机按键摔坏了怎么办 定频空调加错了佛里昂怎么办 定频空调外机噪音大怎么办 老美的定频空调出现p0怎么办 华为揽阅m2青春版卡顿了怎么办 华为揽阅M2青春版发热卡顿怎么办 全民突击网速不给力经常掉线怎么办 华为手机微信视频黑屏了怎么办 相机拍照后找不到拍的照片怎么办 苹果手机下载软件不被信任怎么办 苹果x手机下载软件不受信任怎么办 华为畅享7plus主板坏了怎么办 华为手机手机主板坏了没备份怎么办 华为手机一年内主板坏了怎么办 华为手机保修期内主板坏了怎么办 华为手机外置sd卡满了怎么办 红米4充不进去电怎么办 苹果5s锁屏密码忘记了怎么办 华为手机桌面和锁屏自动一样怎么办 苹果手机没电了没带充电器怎么办 华为p8手机后摄像头模糊的怎么办 中兴手机充电的地方坏了怎么办? 小米手机与电脑蓝牙传输失败怎么办 捡个华为收机没有账号密码怎么办 华为手机p9激活码忘了怎么办 华为畅享7plus声音小怎么办 华为畅享7plus忘记密码怎么办 华为畅享8plus卡顿怎么办 华为畅享7plus卡机怎么办 华为畅享8plus图标字小怎么办 华为畅享6反应慢发热怎么办 华为畅享5S反应迟钝怎么办 华为畅玩5x玩王者荣耀卡怎么办 不小心把手机里的照片删了怎么办 u盘文件在手机上删了怎么办 荒野行动透视挂功能加载失败怎么办 白色t桖衫被奶茶弄脏了该怎么办 游戏文件不小心解压到c盘了怎么办 装系统时c盘0mb怎么办