生成验证码的几种方式详解程序员
程序员 详解 方式 生成 几种 验证码
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
效果如下:
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 /html3,在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
服务器部署程序员系统优化网站设置运维相关文章
- 程序员接私活完整攻略+赠开源管理系统
- docker 镜像创建方式详解程序员
- Linux let 命令详解程序员
- Linux-crontab详解程序员
- 【linux】find删除指定时间之前的文件详解程序员
- HTTP协议请求方式: 中GET、POST和HEAD的介绍以及错误提示码详解程序员
- git reset –hard HEAD^后显示more的原因及如何解决详解程序员
- Python3.x:Linux下退出python命令行详解程序员
- Linux命令之less详解程序员
- Linux命令之lsof详解程序员
- Linux 重定向详解程序员
- Linux 下Shell的学习3-优秀demo详解程序员
- centos7: ifconfig出现command not found解决办法详解程序员
- eclipse不自动弹出提示的解决办法(eclipse alt+/快捷键失效)centos 6.7详解程序员
- tf-idf, CHI, TextRank详解程序员
- 出炉!一线城市程序员工资大调查
- 【程序员你来拯救世界:Linux C开发者招聘】(linuxc招聘)
- 程序员手疼7年查出骨肿瘤:以为是“键盘手”没在意