zl程序教程

您现在的位置是:首页 >  其他

当前栏目

生成验证码的几种方式详解程序员

程序员 详解 方式 生成 几种 验证码
2023-06-13 09:20:03 时间
%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="GBK"% %!Color getRandColor(int fc, int bc) {//给定范围获得随机颜色 Random random = new Random(); if (fc 255) fc = 255; if (bc 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); //设置页面不缓存 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // 在内存中创建图象 // 通过这里可以修改图片大小 int width = 85, height = 23; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 // g相当于笔 Graphics g = image.getGraphics(); //生成随机类 Random random = new Random(); // 设定背景色 g.setColor(getRandColor(200, 250)); // 画一个实心的长方,作为北京 g.fillRect(0, 0, width, height); //设定字体 g.setFont(new Font("黑体", Font.PLAIN, 18)); //画边框 g.setColor(Color.BLUE); g.drawRect(0,0,width-1,height-1); // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 g.setColor(getRandColor(160, 200)); for (int i = 0; i 155; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); // 取随机产生的认证码(4位数字) //String rand = request.getParameter("rand"); //rand = rand.substring(0,rand.indexOf(".")); String sRand = ""; // 如果要使用中文,必须定义字库,可以使用数组进行定义 // 这里直接写中文会出乱码,必须将中文转换为unicode编码 String[] str = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "p", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; for (int i = 0; i i++) { String rand = str[random.nextInt(str.length)]; sRand += rand; // 将认证码显示到图象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random .nextInt(110), 20 + random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 g.drawString(rand, 16 * i + 6, 19); // 将认证码存入SESSION session.setAttribute("rand", sRand); // 图象生效 g.dispose(); // 输出图象到页面 ImageIO.write(image, "JPEG", response.getOutputStream()); out.clear(); out = pageContext.pushBody(); %

login.jsp源码(使用验证码的页面):

//使用验证码的页面login.jsp 

 %@ page contentType="text/html" pageEncoding="GBK"% 

 html 

 head 

 title 登陆页面 /title 

 script 

 function reloadImage() { 

 document.getElementById(identity).src = image.jsp?ts= + new Date() 

 .getTime(); 

 /script 

 /head 

 body 

 center 

 // 乱码解决 

 request.setCharacterEncoding("GBK"); 

 登陆程序 

 /h1 

 %=request.getAttribute("info") != null ? request 

 .getAttribute("info") : ""% 

 form action="check.jsp" method="post" 

 用户ID: 

 input type="text" name="mid" 

 密 码: 

 input type="password" name="password" 

 验证码: 

 input type="text" name="code" maxlength="5" size="5" 

 img src="image.jsp" id="identity" title="看不清,点击换一张" 

 input type="submit" value="登陆" 

 input type="reset" value="重置" 

 /form 

 /center 

 /body 

 /html 

效果如下:

生成验证码的几种方式详解程序员

2,使用Servlet生成验证码

IdentityServlet.java源码:

//IdentityServlet.java代码如下: 

package com.helloweenvsfei.servlet; 

import java.awt.Color; 

import java.awt.Font; 

import java.awt.Graphics2D; 

import java.awt.image.BufferedImage; 

import java.io.IOException; 

import java.util.Random; 

import javax.servlet.ServletException; 

import javax.servlet.ServletOutputStream; 

import javax.servlet.http.HttpServlet; 

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 

import com.sun.image.codec.jpeg.JPEGCodec; 

import com.sun.image.codec.jpeg.JPEGImageEncoder; 

public class IdentityServlet extends HttpServlet { 

 /** 

 private static final long serialVersionUID = -479885884254942306L; 

 public static final char[] CHARS = { 2, 3, 4, 5, 6, 7, 8, 

 9, A, B, C, D, E, F, G, H, J, K, L, M, 

 N, P, Q, R, S, T, U, V, W, X, Y, Z }; 

 public static Random random = new Random(); 

 public static String getRandomString() { 

 StringBuffer buffer = new StringBuffer(); 

 for (int i = 0; i i++) { 

 buffer.append(CHARS[random.nextInt(CHARS.length)]); 

 return buffer.toString(); 

 public static Color getRandomColor() { 

 return new Color(random.nextInt(255), random.nextInt(255), random 

 .nextInt(255)); 

 public static Color getReverseColor(Color c) { 

 return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c 

 .getBlue()); 

 public void doGet(HttpServletRequest request, HttpServletResponse response) 

 throws ServletException, IOException { 

 response.setContentType("image/jpeg"); 

 String randomString = getRandomString(); 

 request.getSession(true).setAttribute("randomString", randomString); 

 int width = 100; 

 int height = 30; 

 Color color = getRandomColor(); 

 Color reverse = getReverseColor(color); 

 BufferedImage bi = new BufferedImage(width, height, 

 BufferedImage.TYPE_INT_RGB); 

 Graphics2D g = bi.createGraphics(); 

 g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16)); 

 g.setColor(color); 

 g.fillRect(0, 0, width, height); 

 g.setColor(reverse); 

 g.drawString(randomString, 18, 20); 

 for (int i = 0, n = random.nextInt(100); i i++) { 

 g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1); 

 // 转成JPEG格式 

 ServletOutputStream out = response.getOutputStream(); 

 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 

 encoder.encode(bi); 

 out.flush(); 

 public static void main(String[] args) { 

 System.out.println(getRandomString()); 

}

Web..xml源码:

//Web.xml的配置为: 

 servlet 

 servlet-name IdentityServlet /servlet-name 

 servlet-class com.helloweenvsfei.servlet.IdentityServlet /servlet-class 

 /servlet 

 servlet-mapping 

 servlet-name IdentityServlet /servlet-name 

 url-pattern /servlet/IdentityServlet /url-pattern 

 /servlet-mapping 

identity.html源码:

//测试页面identity.html为: 

 !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 

 html 

 head 

 title identity.html /title 

 meta http-equiv="keywords" content="keyword1,keyword2,keyword3" 

 meta http-equiv="description" content="this is my page" 

 meta http-equiv="content-type" content="text/html; charset=GB18030" 

 !-- link rel="stylesheet" type="text/css" href="./styles.css" -- 

 /head 

 body 

 script 

 function reloadImage() { 

 document.getElementById(btn).disabled = true; 

 document.getElementById(identity).src=servlet/IdentityServlet?ts= + new Date().getTime(); 

 /script 

 img src="servlet/IdentityServlet" id="identity" onload="btn.disabled = false; " / 

 input type=button value=" 换个图片 " onclick="reloadImage()" id="btn" 

 /body 

 /html 
3,在Struts2应用中生成验证码

RandomNumUtil.java源码:

//RandomNumUtil.java 

package org.ml.util; 

import java.awt.Color; 

import java.awt.Font; 

import java.awt.Graphics; 

import java.awt.image.BufferedImage; 

import java.io.ByteArrayInputStream; 

import java.io.ByteArrayOutputStream; 

import java.util.Random; 

import javax.imageio.ImageIO; 

import javax.imageio.stream.ImageOutputStream; 

public class RandomNumUtil { 

 public static final char[] CHARS = {A, B, C, D, E, F, G, H, J, K, L, M, 

 N, P, Q, R, S, T, U, V, W, X, Y, Z,2, 3, 4, 5, 6, 7, 8, 

 9,a, b, c, d, e, f, g, h, i, j, k, m, 

 n, q, r, s, t, u, v, w, x, y, z}; 

 private ByteArrayInputStream image;// 图像 

 private String str;// 验证码 

 /** 

 * 构造方法调用初始化属性方法 

 private RandomNumUtil() { 

 init(); 

 /** 

 * 取得RandomNumUtil实例 

 public static RandomNumUtil Instance() { 

 return new RandomNumUtil(); 

 /** 

 * 取得验证码图片 

 public ByteArrayInputStream getImage() { 

 return this.image; 

 /** 

 * 取得图片的验证码 

 public String getString() { 

 return this.str; 

 /** 

 * 初始化属性否具体方法 

 private void init() { 

 // 在内存中创建图象 

 int width = 85, height = 18; 

 //设置图形的高度和宽度,以及RGB类型 

 BufferedImage image = new BufferedImage(width, height, 

 BufferedImage.TYPE_INT_RGB); 

 // 获取图形上下文 

 Graphics g = image.getGraphics(); 

 // 生成随机类 

 Random random = new Random(); 

 // 设定背景色 

 g.setColor(getRandColor(200, 250)); 

 g.fillRect(0, 0, width, height); 

 // 设定字体 

 g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); 

 // 随机产生255条干扰线,使图象中的认证码不易被其它程序探测到 

 g.setColor(getRandColor(160, 200)); 

 for (int i = 0; i 255; i++) { 

 int x = random.nextInt(width); 

 int y = random.nextInt(height); 

 int xl = random.nextInt(12); 

 int yl = random.nextInt(12); 

 g.drawLine(x, y, x + xl, y + yl); 

 // 取随机产生的认证码(6位数字) 

 StringBuffer sRand = new StringBuffer(); 

 for (int i = 0; i i++) { 

 String rand = String.valueOf(CHARS[random.nextInt(CHARS.length-1)]);//从字符数组中随机产生一个字符 

 sRand.append(rand); 

 // 将认证码显示到图象中 

 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 

 // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 

 g.drawString(rand, 13 * i + 6, 17); 

 // 赋值验证码 

 this.str = sRand.toString(); 

 // 图象生效 

 g.dispose(); 

 //下面将生成的图形转变为图片 

 ByteArrayOutputStream output = new ByteArrayOutputStream(); 

 ByteArrayInputStream input = null; 

 try { 

 ImageOutputStream imageOut = ImageIO.createImageOutputStream(output); 

 ImageIO.write(image, "JPEG", imageOut);//将图像按JPEG格式写入到imageOut中,即存入到output的字节流中 

 imageOut.close();//关闭写入流 

 input = new ByteArrayInputStream(output.toByteArray());//input读取output中的图像信息 

 } catch (Exception e) { 

 System.out.println("验证码图片产生出现错误:" + e.toString()); 

 this.image = input;/* 赋值图像 */ 

 * 给定范围获得随机颜色 

 private Color getRandColor(int fc, int bc) { 

 Random random = new Random(); 

 if (fc 255) 

 fc = 255; 

 if (bc 255) 

 bc = 255; 

 int r = fc + random.nextInt(bc - fc); 

 int g = fc + random.nextInt(bc - fc); 

 int b = fc + random.nextInt(bc - fc); 

 return new Color(r, g, b); 

}

RandomAction.java源码:

//RandomAction.java的代码: 

package org.ml.action; 

import java.io.ByteArrayInputStream; 

import org.ml.util.RandomNumUtil; 

import com.opensymphony.xwork2.ActionContext; 

import com.opensymphony.xwork2.ActionSupport; 

@SuppressWarnings("serial") 

public class RandomAction extends ActionSupport { 

 private ByteArrayInputStream inputStream; 

 public String execute() throws Exception { 

 RandomNumUtil rdnu = RandomNumUtil.Instance();//取得随机验证码产生类的对象 

 this.setInputStream(rdnu.getImage());// 取得带有随机字符串的图片 

 ActionContext.getContext().getSession().put("random", rdnu.getString());// 取得随机字符串放入HttpSession 

 return SUCCESS; 

 public void setInputStream(ByteArrayInputStream inputStream) { 

 this.inputStream = inputStream; 

 public ByteArrayInputStream getInputStream() { 

 return inputStream; 

}

struts.xml配置:

//struts.xml配置为: 

 !-- Random验证码 -- 

 action name="rand" 

 result type="stream" name="success" 

 param name="contentType" image/JPEG /param 

 param name="inputName" inputStream /param 

 /result 

 /action 

HTML中的表单源码:

//HTML中的表单代码为: 

 tr height="35" 

 td width="14%" 

 span 验证码: /span 

 /td 

 td colspan="2" 

 input type="text" name="rand" id="rand" size="6" 

 maxlength="6" 

 script type="text/javascript" 

 function changeValidateCode(obj) { 

 //获取当前的时间作为参数,无具体意义 

 var timenow = new Date().getTime(); 

 //每次请求需要一个不同的参数,否则可能会返回同样的验证码 

 //这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。 

 obj.src="rand.action?d="+timenow; 

 /script 

 img src="rand.action" title="点击图片刷新验证码" 

 onclick="changeValidateCode(this)" height="22" 

 width="80" / 

 /td 

 /tr 

 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/2552.html

服务器部署程序员系统优化网站设置运维