中文算数验证码(加减乘除)
平台被爬虫爬了。故在网上找了有有趣的验证码。为防止向数据库暴力注册入力。原文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]中文乱码