码迷,mamicode.com
首页 > 编程语言 > 详细

java识别简单的验证码

时间:2015-09-13 00:47:10      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

1.老规矩,先上图

要破解类似这样的验证码:

技术分享

 

拆分后结果:

技术分享

然后去匹配,得到结果。

2.拆分图片

拿到图片后,首先把图片中我们需要的部分截取出来。

具体的做法是,创建一个的和图片像素相同的一个代表权重的二维数组,遍历图片的每个像素点,如果接近白色,就标记为1,否则标记为0;

然后遍历这个二维数据,如果一个竖排都1,说明是空白列,直到第一次遇到不全为1一列,记住列的下标作为起始值,再次遇到全为1的,记住下标作为结束值,然后从起始列到结束列截取图片,依次类推。

 1   //分割图片
 2     private java.util.List<BufferedImage> splitImage(BufferedImage originImg)
 3             throws Exception {
 4         java.util.List<BufferedImage> subImgList = new ArrayList<>();
 5         int height = originImg.getHeight();
 6         int[][] weight = getImgWeight(originImg);
 7         int start = 0;
 8         int end = 0;
 9         boolean isStartReady = false;
10         boolean isEndReady = false;
11         for (int i = 0; i < weight.length; i++) {
12             boolean isBlank = isBlankArr(weight[i]);
13             if (isBlank) {
14                 if (isStartReady && !isEndReady) {
15                     end = i;
16                     isEndReady = true;
17                 }
18             } else {
19                 if (!isStartReady) {
20                     start = i;
21                     isStartReady = true;
22                 }
23             }
24             if (isStartReady && isEndReady) {
25                 subImgList.add(originImg.getSubimage(start, 0, end - start, height));
26                 isStartReady = false;
27                 isEndReady = false;
28             }
29         }
30         return subImgList;
31     }
32 
33     //颜色是否为空白
34     private boolean isBlank(int colorInt) {
35         Color color = new Color(colorInt);
36         return color.getRed() + color.getGreen() + color.getBlue() > 600;
37     }
38 
39     //数组是不是全空白
40     private boolean isBlankArr(int[] arr) {
41         boolean isBlank = true;
42         for (int value : arr) {
43             if (value == 0) {
44                 isBlank = false;
45                 break;
46             }
47         }
48         return isBlank;
49     }
50 
51     //获取图片权重数据
52     private int[][] getImgWeight(BufferedImage img) {
53         int width = img.getWidth();
54         int height = img.getHeight();
55         int[][] weight = new int[width][height];
56         for (int x = 0; x < width; ++x) {
57             for (int y = 0; y < height; ++y) {
58                 if (isBlank(img.getRGB(x, y))) {
59                     weight[x][y] = 1;
60                 }
61             }
62         }
63         return weight;
64     }

 

 

3.与拆分好的图片进行比较

拆分好的图片后,把拆分好的图片再次计算它的权重二维数据,加载之前准备好的"已知值的图片",也计算权重数组。

然后对比两个二维数组,如果大部分都匹配,就确定了值。

如果没有找到匹配的,就把图片保存下来,人工识别后放入已知值的图片组。

 1   //分析识别
 2     private String realize(java.util.List<BufferedImage> imgList) {
 3         String resultStr = "";
 4         for (BufferedImage img : imgList) {
 5             String key = getKey(Global.trainedMap, img);
 6             if (key == null) {
 7                 String noTrainedKey = getKey(Global.noTrainedMap, img);
 8                 if(noTrainedKey == null){
 9                     try {
10                         ImageIO.write(img, "JPG", new File(Global.LIB_NO + File.separator + UUID.randomUUID() + ".jpg"));
11                     } catch (IOException e) {
12                         e.printStackTrace();
13                     }
14                 }
15             } else {
16                 resultStr += key;
17             }
18         }
19         return resultStr;
20     }
21 
22     //获取已知值
23     private String getKey(Map<String, BufferedImage> map, BufferedImage img){
24         String resultStr = null;
25         Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
26         for (Map.Entry<String, BufferedImage> one : entrySet) {
27             if (isSimilarity(img, one.getValue())) {
28                 resultStr = one.getKey();
29                 break;
30             }
31         }
32         return resultStr;
33     }
34 
35     //是否相似
36     private boolean isSimilarity(BufferedImage imageA, BufferedImage imageB) {
37         int widthA = imageA.getWidth();
38         int widthB = imageB.getWidth();
39         int heightA = imageA.getHeight();
40         int heightB = imageB.getHeight();
41         if (widthA != widthB || heightA != heightB) {
42             return false;
43         } else {
44             int[][] weightA = getImgWeight(imageA);
45             int[][] weightB = getImgWeight(imageB);
46             int count = 0;
47             for (int i = 0; i < widthA; i++) {
48                 for (int j = 0; j < heightB; j++) {
49                     if (weightA[i][j] != weightB[i][j]) {
50                         count++;
51                     }
52                 }
53             }
54             if ((double) count / (widthA * widthB) > (1 - Global.SIMILARITY)) {
55                 return false;
56             } else {
57                 return true;
58             }
59         }
60     }

 

4.完整代码

  1 import javax.imageio.ImageIO;
  2 import java.awt.image.BufferedImage;
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.util.HashMap;
  6 import java.util.Map;
  7 
  8 public class Global {
  9     public static final String LIB_PATH = "C:/lib";
 10     public static final String LIB_NO = "C:/no";
 11     public static final double SIMILARITY = 0.9;
 12     public static Map<String, BufferedImage> trainedMap;
 13     public static Map<String, BufferedImage> noTrainedMap = new HashMap<>();
 14 
 15     static {
 16         trainedMap = getMap(LIB_PATH);
 17         noTrainedMap = getMap(LIB_NO);
 18     }
 19 
 20     private static Map<String, BufferedImage>  getMap(String path) {
 21        Map<String, BufferedImage> map = new HashMap<>();
 22         File parentFile = new File(path);
 23         for (String filePath : parentFile.list()) {
 24             File file = new File(path + File.separator + filePath);
 25             String fileName = file.getName();
 26             String key = fileName.substring(0,fileName.indexOf(".")).trim();
 27             try {
 28                 map.put(key, ImageIO.read(file));
 29             } catch (IOException e) {
 30                 e.printStackTrace();
 31             }
 32         }
 33         return map;
 34     }
 35 }
 36 import javax.imageio.ImageIO;
 37 import java.awt.*;
 38 import java.awt.image.BufferedImage;
 39 import java.io.File;
 40 import java.io.IOException;
 41 import java.util.*;
 42 
 43 /**
 44  * 识别验证码
 45  */
 46 public class ImageProcess {
 47     private String imgPath;
 48 
 49     public ImageProcess(String imgPath) {
 50         this.imgPath = imgPath;
 51     }
 52 
 53     public String getResult() {
 54         java.util.List<BufferedImage> imgList = null;
 55         try {
 56             BufferedImage img = ImageIO.read(new File(imgPath));
 57             imgList = splitImage(img);
 58         } catch (IOException e) {
 59             e.printStackTrace();
 60         } catch (Exception e) {
 61             e.printStackTrace();
 62         }
 63         return realize(imgList);
 64     }
 65 
 66     //分析识别
 67     private String realize(java.util.List<BufferedImage> imgList) {
 68         String resultStr = "";
 69         for (BufferedImage img : imgList) {
 70             String key = getKey(Global.trainedMap, img);
 71             if (key == null) {
 72                 String noTrainedKey = getKey(Global.noTrainedMap, img);
 73                 if(noTrainedKey == null){
 74                     try {
 75                         ImageIO.write(img, "JPG", new File(Global.LIB_NO + File.separator + UUID.randomUUID() + ".jpg"));
 76                     } catch (IOException e) {
 77                         e.printStackTrace();
 78                     }
 79                 }
 80             } else {
 81                 resultStr += key;
 82             }
 83         }
 84         return resultStr;
 85     }
 86 
 87     //获取已知值
 88     private String getKey(Map<String, BufferedImage> map, BufferedImage img){
 89         String resultStr = null;
 90         Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
 91         for (Map.Entry<String, BufferedImage> one : entrySet) {
 92             if (isSimilarity(img, one.getValue())) {
 93                 resultStr = one.getKey();
 94                 break;
 95             }
 96         }
 97         return resultStr;
 98     }
 99 
100     //是否相似
101     private boolean isSimilarity(BufferedImage imageA, BufferedImage imageB) {
102         int widthA = imageA.getWidth();
103         int widthB = imageB.getWidth();
104         int heightA = imageA.getHeight();
105         int heightB = imageB.getHeight();
106         if (widthA != widthB || heightA != heightB) {
107             return false;
108         } else {
109             int[][] weightA = getImgWeight(imageA);
110             int[][] weightB = getImgWeight(imageB);
111             int count = 0;
112             for (int i = 0; i < widthA; i++) {
113                 for (int j = 0; j < heightB; j++) {
114                     if (weightA[i][j] != weightB[i][j]) {
115                         count++;
116                     }
117                 }
118             }
119             if ((double) count / (widthA * widthB) > (1 - Global.SIMILARITY)) {
120                 return false;
121             } else {
122                 return true;
123             }
124         }
125     }
126 
127     //分割图片
128     private java.util.List<BufferedImage> splitImage(BufferedImage originImg)
129             throws Exception {
130         java.util.List<BufferedImage> subImgList = new ArrayList<>();
131         int height = originImg.getHeight();
132         int[][] weight = getImgWeight(originImg);
133         int start = 0;
134         int end = 0;
135         boolean isStartReady = false;
136         boolean isEndReady = false;
137         for (int i = 0; i < weight.length; i++) {
138             boolean isBlank = isBlankArr(weight[i]);
139             if (isBlank) {
140                 if (isStartReady && !isEndReady) {
141                     end = i;
142                     isEndReady = true;
143                 }
144             } else {
145                 if (!isStartReady) {
146                     start = i;
147                     isStartReady = true;
148                 }
149             }
150             if (isStartReady && isEndReady) {
151                 subImgList.add(originImg.getSubimage(start, 0, end - start, height));
152                 isStartReady = false;
153                 isEndReady = false;
154             }
155         }
156         return subImgList;
157     }
158 
159     //颜色是否为空白
160     private boolean isBlank(int colorInt) {
161         Color color = new Color(colorInt);
162         return color.getRed() + color.getGreen() + color.getBlue() > 600;
163     }
164 
165     //数组是不是全空白
166     private boolean isBlankArr(int[] arr) {
167         boolean isBlank = true;
168         for (int value : arr) {
169             if (value == 0) {
170                 isBlank = false;
171                 break;
172             }
173         }
174         return isBlank;
175     }
176 
177     //获取图片权重数据
178     private int[][] getImgWeight(BufferedImage img) {
179         int width = img.getWidth();
180         int height = img.getHeight();
181         int[][] weight = new int[width][height];
182         for (int x = 0; x < width; ++x) {
183             for (int y = 0; y < height; ++y) {
184                 if (isBlank(img.getRGB(x, y))) {
185                     weight[x][y] = 1;
186                 }
187             }
188         }
189         return weight;
190     }
191 
192 
193     public static void main(String[] args) throws Exception {
194         String result = new ImageProcess("C:/login.jpg").getResult();
195         System.out.println(result);
196 
197     }
198 }

 

java识别简单的验证码

标签:

原文地址:http://www.cnblogs.com/xiaoxiaoyiran/p/4803886.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!