中文算数验证码(加减乘除)

平台被爬虫爬了。故在网上找了有有趣的验证码。为防止向数据库暴力注册入力。原文http://blog.csdn.net/typa01_kk/article/details/45050091

验证码生成工具类:

  1 package com.etoc.customer.web.tool;
  2 
  3 import java.awt.Color;
  4 import java.awt.Font;
  5 import java.awt.Graphics;
  6 import java.awt.Graphics2D;
  7 import java.awt.image.BufferedImage;
  8 import java.util.HashMap;
  9 import java.util.Map;
 10 import java.util.Random;
 11 
 12 import org.apache.log4j.Logger;
 13 /**
 14  * 
 15  * @ClassName: VerificationCodeTool  
 16  * @Description: 中文算数验证码 
 17  * @author ysq
 18  * @date 2018年2月05日 上午11:18:54 
 19  *
 20  */
 21 public class VerificationCodeTool {
 22     //LOG
 23     private static final Logger LOG =Logger.getLogger(VerificationCodeTool.class);
 24     //验证码宽度
 25     private static final int IMG_WIDTH=146;
 26     //验证码高度
 27     private static final int IMG_HEIGHT=30;
 28     //The number of interference lines
 29     private static final int DISTURB_LINE_SIZE = 15;
 30     //generate a random number
 31     private Random random = new Random();
 32     //验证码结果
 33     private int xyresult;
 34     //验证码
 35     private String randomString;
 36     //Chinese Numbers
 37 //    private static final String [] CNUMBERS = "零,一,二,三,四,五,六,七,八,九,十".split(",");
 38     //零一二三四五六七八九十乘除加减
 39     //Here, must be java Unicode code
 40     private static final String CVCNUMBERS = "\u96F6\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u4E58\u9664\u52A0\u51CF";
 41     //字体
 42     private final Font font = new Font("黑体", Font.BOLD, 18);
 43     
 44     private static final Map<String, Integer> OPMap = new HashMap<String, Integer>();
 45     
 46     static{
 47         OPMap.put("*", 11);
 48         OPMap.put("/", 12);
 49         OPMap.put("+", 13);
 50         OPMap.put("-", 14);
 51     }
 52     /**
 53      * The generation of image  verification code
 54      * */
 55     public BufferedImage drawVerificationCodeImage(){
 56         //image
 57         BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB);
 58         //In memory to create a brush
 59         Graphics g = image.getGraphics();
 60         g.setColor(Color.WHITE);
 61         //image background
 62         g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
 63         //Set the brush color
 64         g.setColor(getRandomColor(200,250));
 65         //image border
 66         g.drawRect(0, 0, IMG_WIDTH-2, IMG_HEIGHT-2);
 67         
 68         //Set disturb line color
 69          g.setColor(getRandomColor(110, 133));
 70          //Generate random interference lines
 71         for(int i =0;i < DISTURB_LINE_SIZE; i++){
 72             drawDisturbLine1(g);
 73             drawDisturbLine2(g);
 74         }
 75         //Generate a random number, set return data
 76         getRandomMathString();
 77         LOG.info("验证码 : "+randomString);
 78         LOG.info("验证码结果 : "+xyresult);
 79         //The generated random string used to save the system
 80         StringBuffer logsu = new StringBuffer();
 81         for(int j=0,k = randomString.length(); j < k; j++){
 82           int chid = 0;
 83           if(j==1){
 84               chid = OPMap.get(String.valueOf(randomString.charAt(j)));
 85           }else{
 86               chid = Integer.parseInt(String.valueOf(randomString.charAt(j)));
 87           }
 88           String ch = String.valueOf(CVCNUMBERS.charAt(chid));
 89           logsu.append(ch);
 90           drawRandomString((Graphics2D)g,ch, j);
 91         }
 92         //= ?
 93         drawRandomString((Graphics2D)g,"\u7B49\u4E8E\uFF1F", 3);
 94         logsu.append("\u7B49\u4E8E \uFF1F");
 95         LOG.info("汉字验证码 : "+logsu);
 96         randomString = logsu.toString();
 97         g.dispose();
 98         return image;
 99     }
100     /**
101      * Get a random string
102      * */
103     private void getRandomMathString(){
104         //Randomly generated number 0 to 10
105         int xx = random.nextInt(10);
106         int yy = random.nextInt(10);
107         //save getRandomString
108         StringBuilder suChinese =  new StringBuilder();
109             //random 0,1,2
110             int Randomoperands = (int) Math.round(Math.random()*2);
111             //multiplication
112             if(Randomoperands ==0){
113                 this.xyresult = yy * xx;
114 //                suChinese.append(CNUMBERS[yy]);
115                 suChinese.append(yy);
116                 suChinese.append("*");
117                 suChinese.append(xx);
118             //division, divisor cannot be zero, Be divisible
119             }else if(Randomoperands ==1){
120                 if(!(xx==0) && yy%xx ==0){
121                     this.xyresult = yy/xx;
122                     suChinese.append(yy);
123                     suChinese.append("/");
124                     suChinese.append(xx);
125                 }else{
126                     this.xyresult = yy + xx;
127                     suChinese.append(yy);
128                     suChinese.append("+");
129                     suChinese.append(xx);
130                 }
131             //subtraction
132             }else if(Randomoperands ==2){
133                     this.xyresult = yy - xx;
134                     suChinese.append(yy);
135                     suChinese.append("-");
136                     suChinese.append(xx);
137             //add
138             }else{
139                     this.xyresult = yy + xx;
140                     suChinese.append(yy);
141                     suChinese.append("+");
142                     suChinese.append(xx);
143             }
144         this.randomString = suChinese.toString();
145     }
146     /**
147      * Draw a random string
148      * @param g Graphics
149      * @param randomString random string
150      * @param i the random number of characters
151      * */
152     public void drawRandomString(Graphics2D g,String randomvcch,int i){
153         //Set the string font style
154         g.setFont(font);
155         //Set the color string
156         int rc = random.nextInt(255);
157         int gc = random.nextInt(255);
158         int bc = random.nextInt(255);
159         g.setColor(new Color(rc, gc, bc));
160         //random string
161         //Set picture in the picture of the text on the x, y coordinates, random offset value
162         int x = random.nextInt(3);
163         int y = random.nextInt(2);
164         g.translate(x, y);
165         //Set the font rotation angle
166         int degree = new Random().nextInt() % 15;
167         //Positive point of view
168         g.rotate(degree * Math.PI / 180, 5+i*25, 20);
169         g.drawString(randomvcch, 5+i*25, 20);
170         //Reverse Angle
171         g.rotate(-degree * Math.PI / 180, 5+i*25, 20);
172     }
173     /**
174      *Draw line interference 
175      *@param g Graphics
176      * */
177     public void drawDisturbLine1(Graphics g){
178         int x1 = random.nextInt(IMG_WIDTH);
179         int y1 = random.nextInt(IMG_HEIGHT);
180         int x2 = random.nextInt(13);
181         int y2 = random.nextInt(15);
182         g.drawLine(x1, y1, x1 + x2, y1 + y2);
183     }
184     
185     /**
186      *Draw line interference 
187      *@param g Graphics
188      * */
189     public void drawDisturbLine2(Graphics g){
190         int x1 = random.nextInt(IMG_WIDTH);
191         int y1 = random.nextInt(IMG_HEIGHT);
192         int x2 = random.nextInt(13);
193         int y2 = random.nextInt(15);
194         g.drawLine(x1, y1, x1 - x2, y1 - y2);
195     }
196     /**
197      * For random color
198      * @param fc fc
199      * @param bc bc
200      * @return color random color
201      * */
202     public Color getRandomColor(int fc,int bc){
203         if(fc > 255){
204             fc = 255;
205         }
206         if(bc > 255){
207             bc = 255;
208         }
209         //Generate random RGB trichromatic
210         int r = fc+random.nextInt(bc -fc - 16);
211         int g = fc+random.nextInt(bc - fc - 14);
212         int b = fc+random.nextInt(bc - fc - 18);
213         return new Color(r, g, b);
214     }
215     
216     /**
217      * 返回初始化验证码图片
218      * 
219      */
220     public int getXyresult() {
221         return xyresult;
222     }
223     
224     /**
225      * randomString.<br/>
226      *
227      * @return  the randomString <br/>
228      * 
229      */
230     public String getRandomString() {
231         return randomString;
232     }
233     
234 }

Controller层(没有用servlet)

 1     @RequestMapping(value = "/getCode", method = {RequestMethod.GET, RequestMethod.POST})
 2     public @ResponseBody void getCode(HttpServletRequest request, HttpServletResponse response){
 3       try{
 4         request.setCharacterEncoding("utf-8");
 5         response.setContentType("text/html;charset=utf-8");
 6         //验证码工具
 7         VerificationCodeTool vcTool = new VerificationCodeTool();
 8         BufferedImage image = vcTool.drawVerificationCodeImage();
 9         //验证码结果
10         int vcResult = vcTool.getXyresult();
11         //验证码
12         String vcValue = vcTool.getRandomString();
13 
14         response.setHeader("Cache-Control", "no-cache");
15         response.setHeader("Pragma", "No-cache");
16         response.setDateHeader("Expires", 0);
17         response.setContentType("image/jpeg");
18         request.getSession().setAttribute("vcResult", vcResult);
19         ImageIO.write(image, "JPEG", response.getOutputStream());
20 //        System.out.println("获取验证码成功 :\n验证码:"+vcValue+"\n验证码结果:"+vcResult);
21     } catch (Exception e) {
22 //        System.out.println("获取验证码失败");
23     }
24   }

 

再说下部署到linux上可能出现的问题(可能服务器上没有验证码上的中文字体):

  1:查看CentOS下”/usr/share/fonts“目录,查看新的系统则为空目录;无目录可手动创建fonts。

  2:打开”C:\Windows\Fonts“等目录下,找到自己需要的字体的目录,那个文件夹也是见名知意了;

  3:之后把挑选的字体,可以建个文件夹,一次传到Xftp等上传到服务器的”/usr/share/fonts“的目录下;

  4:进入"cd /usr/share/fonts"文件夹

  5:最后在此目录下,执行"#fc-cache -fv",扫描字体目录并生成字体信息的缓存,然后应用程序就可以"立即"使用这些新安装的字体;

  6:最终还是要重启web sever,例如:tomcat,字体生效!

  注:在ubuntu中需要安装:apt-get install fontconfig,侯执行以下命令!     

      附上详情解决方法:Linux环境下"Font font = new Font("黑体", Font.BOLD, 18)"[BufferedImage~Graphics~drawString]中文乱码

posted @ 2018-02-05 17:55  幼稚园小班大佬  阅读(2586)  评论(0编辑  收藏  举报