验证码的简单实现:字母数字混合验证码+算术验证码

mac2026-04-19  7

当然可以使用框架了。本文是介绍如何手写一个简单的验证码.


字母数字混合验证码:

首先先处理生成字母和数字:

/** * 产生随机数字和字母 * @return */ private static char randomChar(){ //定义验证需要的字母和数字 String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789"; Random random = new Random(); return str.charAt(random.nextInt(str.length())); }

正如你所看到的,很简单。

然后就是验证码的绘制了:

public static String drawImage(HttpServletResponse response){ StringBuilder builder = new StringBuilder(); for (int i = 0; i < 4; i++) { builder.append(randomChar()); } String code = builder.toString(); //定义图片的宽度和高度 int width = 120; int height = 25; //建立bufferedImage对象,制定图片的长度和宽度以及色彩 BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); //获取Graphics2D,开始绘制验证码 Graphics2D g = bi.createGraphics(); Font font = new Font("微软雅黑",Font.PLAIN,20); Color color = new Color(255, 255, 255); g.setFont(font); g.setColor(color); g.setBackground(new Color(41,214,204)); g.clearRect(0,0,width,height); //绘制形状 FontRenderContext context = g.getFontRenderContext(); Rectangle2D bounds= font.getStringBounds(code,context); //计算文字的坐标和间距 double x = (width - bounds.getWidth())/2; double y = (height - bounds.getHeight())/2; double ascent = bounds.getY(); double baseY = y -ascent; g.drawString(code,(int)x,(int)baseY); //结束绘制 g.dispose(); // try { ImageIO.write(bi,"jpg",response.getOutputStream()); //刷新响应流 response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); } return code; }

完整代码:

package com.verificationcode.yinlei; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * 验证码工具类 */ public class CaptcahCode { /** * 验证码的生成方法 * @param response * @return */ public static String drawImage(HttpServletResponse response){ StringBuilder builder = new StringBuilder(); for (int i = 0; i < 4; i++) { builder.append(randomChar()); } String code = builder.toString(); //定义图片的宽度和高度 int width = 120; int height = 25; //建立bufferedImage对象,制定图片的长度和宽度以及色彩 BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); //获取Graphics2D,开始绘制验证码 Graphics2D g = bi.createGraphics(); Font font = new Font("微软雅黑",Font.PLAIN,20); Color color = new Color(255, 255, 255); g.setFont(font); g.setColor(color); g.setBackground(new Color(41,214,204)); g.clearRect(0,0,width,height); //绘制形状 FontRenderContext context = g.getFontRenderContext(); Rectangle2D bounds= font.getStringBounds(code,context); //计算文字的坐标和间距 double x = (width - bounds.getWidth())/2; double y = (height - bounds.getHeight())/2; double ascent = bounds.getY(); double baseY = y -ascent; g.drawString(code,(int)x,(int)baseY); //结束绘制 g.dispose(); // try { ImageIO.write(bi,"jpg",response.getOutputStream()); //刷新响应流 response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); } return code; } /** * 产生随机数字和字母 * @return */ private static char randomChar(){ //定义验证需要的字母和数字 String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789"; Random random = new Random(); return str.charAt(random.nextInt(str.length())); } }

code.jsp:

<%@ page import="com.verificationcode.yinlei.CaptcahCode" %><%-- Created by IntelliJ IDEA. User: 10991 Date: 2019/11/2 Time: 11:19 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% //1.清空浏览器的缓存 response.setHeader("pragma","no-cache"); response.setHeader("cache-control","no-cache"); response.setHeader("expires","0"); //调用生成验证码的工具类 String code = CaptcahCode.drawImage(response); session.setAttribute("code",code); out.clear(); out = pageContext.pushBody(); %> </body> </html>

index.jsp:

<%@ page import="com.verificationcode.yinlei.CaptcahCode" %><%-- Created by IntelliJ IDEA. User: 10991 Date: 2019/11/2 Time: 10:53 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>验证码</title> </head> <body> <img src="code.jsp" id="code"> <a href="javascript:void(0);" onclick="changeCode()">看不清?换一张</a> <script> function changeCode() { document.getElementById("code").src="code.jsp?d="+new Date().getTime(); } </script> </body> </html>

算术验证码:

/** * 算术表达式验证码 * 干扰线的产生 * 范围随机颜色、随机数 * @param response * @return */ public static String drawImageVerificate(HttpServletResponse response){ int width = 100; int height = 30; BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); Random random = new Random(); g.setColor(getRandomColor(240,250)); g.setFont(new Font("微软雅黑",Font.PLAIN,22)); g.fillRect(0,0,width,height); //干扰线的绘制:绘制线条到图片中 g.setColor(getRandomColor(180,230)); for (int i = 0; i < 100; i++) { int x= random.nextInt(width); int y= random.nextInt(height); int x1 = random.nextInt(60); int y1 = random.nextInt(60); g.drawLine(x,y,x1,y1); } //算术表达式的拼接 int num1= (int) (Math.random()*10+1); int num2= (int) (Math.random()*10+1); int fuhao = random.nextInt(4);//产生一个[0,3]之间的随机整数 String fuhaostr = null; int result =0; switch (fuhao){ case 0: fuhaostr = "+"; result=num1+num2; break; case 1: fuhaostr = "-"; result=num1-num2; break; case 2: fuhaostr = "*"; result=num1*num2; break; case 3: fuhaostr = "/"; result=num1/num2; break; } String calc = num1+" "+fuhaostr+" "+num2 + " = ?"; g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110))); g.drawString(calc,5,25); g.dispose(); try { ImageIO.write(image,"JPEG",response.getOutputStream()); return String.valueOf(result); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 范围随机颜色 * @param fc * @param bc * @return */ public static Color getRandomColor(int fc, int bc){ Random random = new Random(); //随机颜色,了解颜色Color(red,green,blue),rgb3元色 0 - 255 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); }

工具类源代码:

package com.verificationcode.yinlei; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * 验证码工具类 */ public class CaptcahCode { /** * 验证码的生成方法 * @param response * @return */ public static String drawImage(HttpServletResponse response){ StringBuilder builder = new StringBuilder(); for (int i = 0; i < 4; i++) { builder.append(randomChar()); } String code = builder.toString(); //定义图片的宽度和高度 int width = 120; int height = 25; //建立bufferedImage对象,制定图片的长度和宽度以及色彩 BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); //获取Graphics2D,开始绘制验证码 Graphics2D g = bi.createGraphics(); Font font = new Font("微软雅黑",Font.PLAIN,20); Color color = new Color(255, 255, 255); g.setFont(font); g.setColor(color); g.setBackground(new Color(41,214,204)); g.clearRect(0,0,width,height); //绘制形状 FontRenderContext context = g.getFontRenderContext(); Rectangle2D bounds= font.getStringBounds(code,context); //计算文字的坐标和间距 double x = (width - bounds.getWidth())/2; double y = (height - bounds.getHeight())/2; double ascent = bounds.getY(); double baseY = y -ascent; g.drawString(code,(int)x,(int)baseY); //结束绘制 g.dispose(); // try { ImageIO.write(bi,"jpg",response.getOutputStream()); //刷新响应流 response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); } return code; } /** * 算术表达式验证码 * 干扰线的产生 * 范围随机颜色、随机数 * @param response * @return */ public static String drawImageVerificate(HttpServletResponse response){ int width = 100; int height = 30; BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); Random random = new Random(); g.setColor(getRandomColor(240,250)); g.setFont(new Font("微软雅黑",Font.PLAIN,22)); g.fillRect(0,0,width,height); //干扰线的绘制:绘制线条到图片中 g.setColor(getRandomColor(180,230)); for (int i = 0; i < 100; i++) { int x= random.nextInt(width); int y= random.nextInt(height); int x1 = random.nextInt(60); int y1 = random.nextInt(60); g.drawLine(x,y,x1,y1); } //算术表达式的拼接 int num1= (int) (Math.random()*10+1); int num2= (int) (Math.random()*10+1); int fuhao = random.nextInt(4);//产生一个[0,3]之间的随机整数 String fuhaostr = null; int result =0; switch (fuhao){ case 0: fuhaostr = "+"; result=num1+num2; break; case 1: fuhaostr = "-"; result=num1-num2; break; case 2: fuhaostr = "*"; result=num1*num2; break; case 3: fuhaostr = "/"; result=num1/num2; break; } String calc = num1+" "+fuhaostr+" "+num2 + " = ?"; g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110))); g.drawString(calc,5,25); g.dispose(); try { ImageIO.write(image,"JPEG",response.getOutputStream()); return String.valueOf(result); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 范围随机颜色 * @param fc * @param bc * @return */ public static Color getRandomColor(int fc, int bc){ Random random = new Random(); //随机颜色,了解颜色Color(red,green,blue),rgb3元色 0 - 255 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); } /** * 产生随机数字和字母 * @return */ private static char randomChar(){ //定义验证需要的字母和数字 String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789"; Random random = new Random(); return str.charAt(random.nextInt(str.length())); } }

 

最新回复(0)