jsp验证码
在程序登录或注册时,为了防止某些别有用心的用户利用机器人(恶意程序)自动注册,登录、恶意灌水、恶意增加数据库访问,以及使用程序暴力破解程序代码,就需要使用验证码技术。验证码是一种区分用户是计算机还是人的自动程序,虽然需要人来解答,但是也必须只能有人才能解答。由于计算机无法解答CAPTEHA(验证码)的问题,所以回答问题的用户就可以认为是人。
目前常见的验证码有以下几种。
(1)纯数字验证码或纯字母。即随机地产生若干长度的数字或字母,这是最简单的验证码。
(2)数字加字母混合验证码。随机产生若干数字和字母连接成字符串,写入图片中,输出到页面上。
(3)汉字验证码。它是目前最新验证码,它随机生成汉字。但用户输入时比较麻烦。
(4)问题验证码。例如图片中显示“1+2=?”,用户必须填写正确答案才能通过验证,一般页面上会有提示。
下面是一些简单的常用的验证码源码。
一、jsp文件验证码:checknum.jsp(纯数字)
1 <%@page import="javax.imageio.ImageIO"%> 2 <%@page import="java.awt.Font"%> 3 <%@page import="java.awt.Graphics"%> 4 <%@page import="java.awt.image.BufferedImage"%> 5 <%@page import="java.util.Random"%> 6 <%@page import="java.awt.Color"%> 7 <%@ page language="java" contentType="text/html; charset=UTF-8" 8 pageEncoding="UTF-8"%> 9 <%! 10 Color getRandColor(int fc,int bc){//给定范围获取随机颜色 11 Random random = new Random(); 12 if(fc>255)fc=255; 13 if(bc>255)bc=255; 14 int r = fc+random.nextInt(bc-fc); 15 int g = fc+random.nextInt(bc-fc); 16 int b = fc+random.nextInt(bc-fc); 17 return new Color(r,g,b); 18 } 19 %> 20 <% 21 response.setHeader("Pragma", "No-catche");//设置页面不缓存 22 response.setHeader("Cache-Control", "no-cache"); 23 response.setDateHeader("Expires", 0); 24 int width = 80, height = 25; 25 BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); 26 Graphics g = image.getGraphics();//获取图形上下文 27 Random random = new Random();//生成随机对象 28 g.setColor(getRandColor(200, 250));//设定背景颜色 29 g.fillRect(0, 0, width, height); 30 g.setFont(new Font("Times New Roman",Font.PLAIN,18));//设定字体 31 //随机产生155条干扰线,是图像中的验证码不易被其他程序探测到 32 g.setColor(getRandColor(160, 220)); 33 for(int i = 0; i < 200; i++){ 34 int x = random.nextInt(width); 35 int y = random.nextInt(height); 36 int x1 = random.nextInt(12); 37 int y1 = random.nextInt(12); 38 g.drawLine(x, y, x+x1, y+y1); 39 } 40 //随机产生验证码(4位) 41 String sRand = ""; 42 for(int i = 0; i < 4; i++){ 43 String rand = String.valueOf(random.nextInt(10)); 44 sRand = rand; 45 //将验证码显示到图像中 46 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 47 //设置随机字符的颜色 48 g.drawString(rand, 13*i+6, 16); 49 } 50 session.setAttribute("vifity", sRand);//将随机验证码写入session 51 g.dispose();//图像生效 52 //输出到页面 53 ImageIO.write(image, "JPEG", response.getOutputStream()); 54 out.clear(); 55 out = pageContext.pushBody(); 56 %>
在页面中使用: <img alt="Change" src="checknum.jsp" /> //验证码与页面在同一目录下
效果:
二、servlet验证码
(1)纯数字验证码CheckNum.java
1 package Check; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.IOException; 8 import java.util.Random; 9 10 import javax.servlet.ServletException; 11 import javax.servlet.ServletOutputStream; 12 import javax.servlet.annotation.WebServlet; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.HttpSession; 17 18 import com.sun.image.codec.jpeg.JPEGCodec; 19 import com.sun.image.codec.jpeg.JPEGImageEncoder; 20 21 /** 22 * Servlet implementation class ChenkNum 23 */ 24 @WebServlet("/ChenkNum") 25 public class CheckNum extends HttpServlet { 26 private static final long serialVersionUID = 1L; 27 private Font mFont = new Font("Times new Roman",Font.PLAIN,18);//设置字体 28 29 /** 30 * @see HttpServlet#HttpServlet() 31 */ 32 public CheckNum() { 33 super(); 34 // TODO Auto-generated constructor stub 35 } 36 37 /** 38 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 39 */ 40 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 41 // TODO Auto-generated method stub 42 HttpSession session = request.getSession(false); 43 response.setContentType("image/gif"); 44 response.setHeader("Pragma", "No-cache"); 45 response.setHeader("Cache-Control", "nu-cache"); 46 response.setDateHeader("Expires", 0); 47 int width = 60,height = 25; 48 ServletOutputStream out = response.getOutputStream(); 49 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//设置图片大小 50 Graphics gra = image.getGraphics(); 51 Random random = new Random(); 52 gra.setColor(getRandColor(200,250));//设置背景颜色 53 gra.fillRect(0, 0, width, height); 54 gra.setColor(Color.black);//设置字体颜色 55 gra.setFont(mFont); 56 //随机产生155条干扰线 57 gra.setColor(getRandColor(160, 200)); 58 for(int i = 0; i < 155; i++){ 59 int x = random.nextInt(width); 60 int y = random.nextInt(height); 61 int x1 = random.nextInt(12); 62 int y1 = random.nextInt(12); 63 gra.drawLine(x, y, x+x1, y+y1); 64 } 65 //随机产生算数表达试 66 String sRand = ""; 67 for(int i = 0; i < 4; i++){ 68 String rand = String.valueOf(random.nextInt(10)); 69 sRand = rand; 70 //将算数表达试写入图像 71 gra.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 72 gra.drawString(rand, 13*i+6, 16); 73 } 74 //将正确结果写入session 75 session.setAttribute("vifity", sRand); 76 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 77 encoder.encode(image); 78 out.close(); 79 } 80 81 private static Color getRandColor(int fc, int bc) { 82 Random random = new Random(); 83 if(fc > 255) 84 fc = 255; 85 if(bc > 255) 86 bc = 255; 87 int r = fc + random.nextInt(bc - fc); 88 int g = fc + random.nextInt(bc - fc); 89 int b = fc + random.nextInt(bc - fc); 90 return new Color(r,g,b); 91 } 92 93 /** 94 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 95 */ 96 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 97 // TODO Auto-generated method stub 98 } 99 }
页面使用:<img alt="Change" src="CheckNum" />
效果:
(2)数字加字母混合验证码:CheckNumString.java
1 package Check; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.IOException; 8 import java.io.PrintWriter; 9 import java.util.Random; 10 11 import javax.servlet.ServletException; 12 import javax.servlet.ServletOutputStream; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.HttpSession; 17 18 import com.sun.image.codec.jpeg.JPEGCodec; 19 import com.sun.image.codec.jpeg.JPEGImageEncoder; 20 21 public class CheckNumString extends HttpServlet { 22 private static final long serialVersionUID = 1L; 23 private Font mFont = new Font("Times new Roman",Font.PLAIN,18);//设置字体 24 25 /** 26 * The doGet method of the servlet. <br> 27 * 28 * This method is called when a form has its tag value method equals to get. 29 * 30 * @param request the request send by the client to the server 31 * @param response the response send by the server to the client 32 * @throws ServletException if an error occurred 33 * @throws IOException if an error occurred 34 */ 35 public void doGet(HttpServletRequest request, HttpServletResponse response) 36 throws ServletException, IOException { 37 HttpSession session = request.getSession(false); 38 response.setContentType("image/gif"); 39 response.setHeader("Pragma", "No-cache"); 40 response.setHeader("Cache-Control", "nu-cache"); 41 response.setDateHeader("Expires", 0); 42 int width = 60,height = 25; 43 ServletOutputStream out = response.getOutputStream(); 44 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//设置图片大小 45 Graphics gra = image.getGraphics(); 46 Random random = new Random(); 47 gra.setColor(getRandColor(200,250));//设置背景颜色 48 gra.fillRect(0, 0, width, height); 49 gra.setColor(Color.black);//设置字体颜色 50 gra.setFont(mFont); 51 //随机产生155条干扰线 52 gra.setColor(getRandColor(160, 200)); 53 for(int i = 0; i < 155; i++){ 54 int x = random.nextInt(width); 55 int y = random.nextInt(height); 56 int x1 = random.nextInt(12); 57 int y1 = random.nextInt(12); 58 gra.drawLine(x, y, x+x1, y+y1); 59 } 60 //随机产生算数表达试 61 String str = "qwertyuioplkjhgfdsazxcvbnmMNBVCXZASDFGHJKLPOIUYTREWQ1234567890"; 62 String sRand = ""; 63 for(int i = 0; i < 4; i++){ 64 int begin = random.nextInt(62); 65 String c = str.substring(begin, begin+1); 66 String rand = sRand + c; 67 gra.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 68 gra.drawString(rand, 13*i+6, 16); 69 } 70 //将正确结果写入session 71 session.setAttribute("vifity", sRand); 72 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 73 encoder.encode(image); 74 out.close(); 75 } 76 private static Color getRandColor(int fc, int bc) { 77 Random random = new Random(); 78 if(fc > 255) 79 fc = 255; 80 if(bc > 255) 81 bc = 255; 82 int r = fc + random.nextInt(bc - fc); 83 int g = fc + random.nextInt(bc - fc); 84 int b = fc + random.nextInt(bc - fc); 85 return new Color(r,g,b); 86 } 87 }
页面使用:<img alt="Change" src="CheckNumString" />
效果:
(3)问题验证码:CheckMath.java
1 package Check; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.IOException; 8 import java.io.PrintWriter; 9 import java.util.Random; 10 11 import javax.servlet.ServletException; 12 import javax.servlet.ServletOutputStream; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.HttpSession; 17 18 import com.sun.image.codec.jpeg.JPEGCodec; 19 import com.sun.image.codec.jpeg.JPEGImageEncoder; 20 21 public class CheckMath extends HttpServlet { 22 private Font mFont = new Font("Times new Roman",Font.PLAIN,18);//设置字体 23 24 /** 25 * The doGet method of the servlet. <br> 26 * 27 * This method is called when a form has its tag value method equals to get. 28 * 29 * @param request the request send by the client to the server 30 * @param response the response send by the server to the client 31 * @throws ServletException if an error occurred 32 * @throws IOException if an error occurred 33 */ 34 public void doGet(HttpServletRequest request, HttpServletResponse response) 35 throws ServletException, IOException { 36 HttpSession session = request.getSession(false); 37 response.setContentType("image/gif"); 38 response.setHeader("Pragma", "No-cache"); 39 response.setHeader("Cache-Control", "no-cache"); 40 response.setDateHeader("Expires", 0); 41 int width = 80, height = 25; 42 ServletOutputStream out = response.getOutputStream(); 43 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//设置图片大小 44 Graphics gra = image.getGraphics(); 45 Random random = new Random(); 46 gra.setColor(getRandColor(200,255));//设置背景颜色 47 gra.fillRect(0, 0, width, height); 48 gra.setColor(Color.black);//设置字体颜色 49 gra.setFont(mFont); 50 //随机产生155条干扰线 51 gra.setColor(getRandColor(160, 200)); 52 for(int i = 0; i < 155; i++){ 53 int x = random.nextInt(width); 54 int y = random.nextInt(height); 55 int x1 = random.nextInt(12); 56 int y1 = random.nextInt(12); 57 gra.drawLine(x, y, x+x1, y+y1); 58 } 59 //随机产生算数表达试 60 int num1 = random.nextInt(100); 61 int num2 = random.nextInt(100); 62 //将算数表达试写入图像 63 String rand = String.valueOf(num1)+"+"+String.valueOf(num2)+"=?"; 64 gra.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 65 gra.drawString(rand, 15, 20); 66 int num3 = num1 + num2; 67 //将正确结果写入session 68 session.setAttribute("vifity1", rand); 69 session.setAttribute("num1", num1); 70 session.setAttribute("num2", num2); 71 session.setAttribute("num3", num3); 72 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 73 encoder.encode(image); 74 out.close(); 75 } 76 77 private Color getRandColor(int fc, int bc) { 78 // TODO 自动生成的方法存根 79 Random random = new Random(); 80 if(fc > 255) 81 fc = 255; 82 if(bc > 255) 83 bc = 255; 84 int r = fc + random.nextInt(bc - fc); 85 int g = fc + random.nextInt(bc - fc); 86 int b = fc + random.nextInt(bc - fc); 87 return new Color(r,g,b); 88 } 89 }
页面使用:<img alt="Change" src="CheckMath" />
效果:
(4)中文验证码:CheckChines.java
1 package Check; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.IOException; 8 import java.io.PrintWriter; 9 import java.util.Random; 10 11 import javax.servlet.ServletException; 12 import javax.servlet.ServletOutputStream; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.HttpSession; 17 18 import com.sun.image.codec.jpeg.JPEGCodec; 19 import com.sun.image.codec.jpeg.JPEGImageEncoder; 20 21 public class CheckChines extends HttpServlet { 22 private static final long serialVersionUID = 1L; 23 private Font mFont = new Font("宋体", Font.ITALIC, 26);//设置字体 24 25 /** 26 * The doGet method of the servlet. <br> 27 * 28 * This method is called when a form has its tag value method equals to get. 29 * 30 * @param request the request send by the client to the server 31 * @param response the response send by the server to the client 32 * @throws ServletException if an error occurred 33 * @throws IOException if an error occurred 34 */ 35 public void doGet(HttpServletRequest request, HttpServletResponse response) 36 throws ServletException, IOException { 37 HttpSession session = request.getSession(false); 38 response.setContentType("image/gif"); 39 response.setHeader("Pragma", "No-cache"); 40 response.setHeader("Cache-Control", "nu-cache"); 41 response.setDateHeader("Expires", 0); 42 int width = 110,height = 30; 43 ServletOutputStream out = response.getOutputStream(); 44 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//设置图片大小 45 Graphics gra = image.getGraphics(); 46 Random random = new Random(); 47 gra.setColor(getRandColor(200,250));//设置背景颜色 48 gra.fillRect(0, 0, width, height); 49 gra.setColor(Color.black);//设置字体颜色 50 gra.setFont(mFont); 51 //随机产生100条干扰线 52 gra.setColor(getRandColor(160, 200)); 53 for(int i = 0; i < 100; i++){ 54 int x = random.nextInt(width); 55 int y = random.nextInt(height); 56 int x1 = random.nextInt(12); 57 int y1 = random.nextInt(12); 58 gra.drawLine(x, y, x+x1, y+y1); 59 } 60 //随机产生算数表达试 61 String sRand = ""; 62 String rand = ""; 63 StringBuffer sb = new StringBuffer(); 64 for(int i = 0; i < 4; i++){ 65 String c = drawRandomChineseChar(); 66 rand = sRand + c; 67 gra.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 68 gra.drawString(rand, 24*i+6, 24); 69 sb.append(rand); 70 } 71 //将正确结果写入session 72 session.setAttribute("vifity2", sb); 73 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 74 encoder.encode(image); 75 out.close(); 76 } 77 //产生汉字方法 78 // 汉字"啊"在汉字16区01位码位置,内码:0xb0,0xa1。汉字符集在94*94区中间, 79 // 前15区是符号,常用汉字区码在16-87中间,位码01-94 80 private String drawRandomChineseChar() { 81 Random random = new Random(); 82 StringBuffer sb = new StringBuffer(); 83 String temp = ""; 84 String[] rBase = {"0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , 85 "8" , "9" , "a" , "b" , "c" , "d" , "e" , "f" }; 86 int r1 = random.nextInt(5)+11 ; //生成第1位的区码 87 String strR1 = rBase[r1] ; //生成11~15的随机数 88 int r2 ; //生成第2位的区码 89 if(r1 == 15) 90 r2 = random.nextInt(7) ; //生成0~7的随机数 91 else 92 r2 = random.nextInt(16) ; //生成0~16的随机数 93 String strR2 = rBase[r2] ; 94 int r3 = random.nextInt(6) + 10 ; //生成第1位的位码 95 String strR3 = rBase[r3] ; 96 int r4 ; //生成第2位的位码 97 if(r3 == 10) 98 r4 = random.nextInt(15) + 1; //生成1~16的随机数 99 else if(r3 == 15) 100 r4 = random.nextInt(15) ; //生成0~15的随机数 101 else 102 r4 = random.nextInt(16) ; //生成0~16的随机数 103 String strR4 = rBase[r4] ; 104 //将生成的机内码转换成数字 105 byte[] bytes = new byte[2] ; 106 String strR12 = strR1 + strR2 ; //将生成的区码保存到字节数组的第1个元素中 107 int tempLow = Integer.parseInt(strR12, 16) ; 108 bytes[0] = (byte)tempLow; 109 String strR34 = strR3 + strR4 ; //将生成的区码保存到字节数组的第2个元素中 110 int tempHigh = Integer.parseInt(strR34, 16) ; 111 bytes[1] = (byte)tempHigh; 112 temp = new String(bytes); //根据字节数组生成汉字 113 sb.append(temp); 114 return sb.toString(); 115 } 116 private static Color getRandColor(int fc, int bc) { 117 Random random = new Random(); 118 if(fc > 255) 119 fc = 255; 120 if(bc > 255) 121 bc = 255; 122 int r = fc + random.nextInt(bc - fc); 123 int g = fc + random.nextInt(bc - fc); 124 int b = fc + random.nextInt(bc - fc); 125 return new Color(r,g,b); 126 } 127 }
页面使用:<img alt="Change" src="CheckChines" />
效果: