使用JAVA生成四位随机验证码图片
- 格式:docx
- 大小:13.86 KB
- 文档页数:3
java实现验证码完整版第一步:在web.xml中配置servlet<servlet><servlet-name>ImageServlet</servlet-name><servlet-class>org.servlet.ImageServlet</servlet-class> </servlet><servlet-mapping><servlet-name>ImageServlet</servlet-name><url-pattern>/ImageServlet</url-pattern></servlet-mapping>第二步: ImageServlet 实现import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.farm.web.tool.RandomValidateCode;public class ImageServlet extends HttpServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("image/jpeg");// 设置相应类型,告诉浏览器输出的内容为图片response.setHeader("Pragma", "No-cache");// 设置响应头信息,告诉浏览器不要缓存此内容response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expire", 0);RandomValidateCode randomValidateCode = new RandomValidateCode();try {randomValidateCode.getRandcode(request, response);// 输出图片方法} catch (Exception e) {e.printStackTrace();}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class RandomValidateCode {public static String validateCode = null;public static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";// 放到session中的keyprivate Random random = new Random();private String randString ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 随机产生的字符串private int width = 80;// 图片宽private int height = 26;// 图片高private int lineSize = 40;// 干扰线数量private int stringNum = 4;// 随机产生字符数量/** 获得字体*/private Font getFont() {return new Font("Fixedsys", Font.CENTER_BASELINE, 18);}/** 获得颜色*/private Color getRandColor(int fc, int bc) {if (fc > 255)fc = 255;if (bc > 255)bc = 255;int r = fc + random.nextInt(bc - fc - 16);int g = fc + random.nextInt(bc - fc - 14);int b = fc + random.nextInt(bc - fc - 18);return new Color(r, g, b);}/*** 生成随机图片*/public void getRandcode(HttpServletRequest request,HttpServletResponse response) {HttpSession session = request.getSession();// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_BGR);Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作g.fillRect(0, 0, width, height);g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE,18));g.setColor(getRandColor(110, 133));// 绘制干扰线for (int i = 0; i <= lineSize; i++) {drowLine(g);}// 绘制随机字符String randomString = "";for (int i = 1; i <= stringNum; i++) {randomString = drowString(g, randomString, i);}session.removeAttribute(RANDOMCODEKEY);session.setAttribute(RANDOMCODEKEY, randomString);validateCode = randomString.toUpperCase();g.dispose();try {ImageIO.write(image, "JPEG",response.getOutputStream());// 将内存中的图片通过流动形式输出到客户端} catch (Exception e) {e.printStackTrace();}}/** 绘制字符串*/private String drowString(Graphics g, String randomString, int i) {g.setFont(getFont());g.setColor(new Color(random.nextInt(101), random.nextInt(111), random.nextInt(121)));String rand =String.valueOf(getRandomString(random.nextInt(randString.length())));randomString += rand;g.translate(random.nextInt(3), random.nextInt(3));g.drawString(rand, 13 * i, 16);return randomString;}/** 绘制干扰线*/private void drowLine(Graphics g) {int x = random.nextInt(width);int y = random.nextInt(height);int xl = random.nextInt(13);int yl = random.nextInt(15);g.drawLine(x, y, x + xl, y + yl);}/** 获取随机的字符*/public String getRandomString(int num) {return String.valueOf(randString.charAt(num)); }}第三步:jsp展现<tr><td><div align="right">验证码:</div></td><td><input style="width: 65px" id="validatecode"name="validatecode" type="text" /></td><td><img title="看不清楚,换一张?" style="cursor: pointer;" onclick="javascript:refresh(this);"src="<PF:basePath/>/ImageServlet"></td></tr>src路径根据情况修改function refresh(obj) {obj.src = "<PF:basePath/>/ImageServlet?"+Math.random();}第四步:Action验证if(RandomValidateCode.validateCode!=null&&validatecode.trim().toUpperCa se().equals(RandomValidateCode.validateCode)){System.out.println("验证码正确");}。
南昌航空大学实验报告2015年月日课程名称: 信息安全概论实验名称:验证码的Java实现学号:姓名:指导老师评定: 签名:一、实验目的通过实验了解验证码的原理,掌握Java语言验证码的实现。
二、实验原理1.验证码的定义验证码(CAPTCHA)是“Completely Automated Public Turing testto tellComputers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
这个问题可以由计算机生成并评判,但是必须只有人类才能解答。
由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。
2.验证码的作用:可以防止恶意破解密码、刷票、论坛灌水,有效防止黑客对注册用户用特定程序暴力破解方式进行不断地登录尝试,实际上用验证码是现在很多网站通行的方式。
利用比较简易的方式实现这个功能,虽然登录麻烦一点,但是对用户的密码安全来说这个功能还是很有必要,也很重要。
3.验证码的使用大多数网站的验证码都是需要点击一下填写框,然后会自动弹出验证码图片。
由于验证码是随机产生的,有很大几率会出现无法清楚识别的验证码图片,所以需要注意的是,一般网站都会有相应的提示,如“看不清,换一张”等,如果没有提示,则直接点击当前的验证码图片,可以完成验证码的更换。
(1)登录时使用:防止暴力破解密码(2)注册时使用:防止自动批量注册(3)发帖时使用:防止自动灌水、发广告三、实验环境开发工具:JDK、Eclipse参考资料:JDK API文档java.awt包java.awt.event包javax.swing包四、实验内容和任务使用Java语言编程,实现登录时生成验证码的功能。
五、实验要求(1)登录时,系统随机生成验证码,并显示在图片中;(2)用户输入用户名、密码和验证码后,系统先判断验证码是否正确,如果不正确,则重新随机生成一个新的验证码,等待用户再次输入;(3)如果输入的验证码正确,再判断用户名和密码是否正确,判断是否登录成功。
javaweb项⽬中表单⽣成的验证码以及校验⾸先先来看⼀下项⽬的结构吧,有两个servlet,⼀个是进⾏验证码的⽣成以及存储的,⼀个是进⾏校验的,还有⼀个jsp页⾯是⽤来实现form表单的书写和展⽰:我们只需要看这三个就⾏了,其他的⾃动忽略;记得写完以后要配置⼀下web.xml⾥⾯的路径,不然访问不到servlet⾥⾯的内容。
说⼀下思路:我们使⽤BufferedImage把绘制出来的传递到前台,然后把⽣成的随即数字存到session⾥⾯,然后再在表单验证的java当中提取session⾥⾯的数值进⾏⽐较:绘制验证码的servlet:package Response;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.util.Random;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.imageio.ImageIO;import java.io.IOException;@WebServlet(name = "Response03", urlPatterns = {"/Response/Response03"})public class Response03 extends HttpServlet {public static final long serialVersionUID = 3038623696184546092L;public static final int WIDTH = 120; //⽣成图⽚的宽度public static final int HEIGHT = 30;//⽣成图⽚的长度protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setHeader("refresh", "2"); //设置响应头控制浏览器每隔3S刷新页⾯String createTypeFlag = request.getParameter("createTypeFlag");//向客户端传递的createTypeFlag标识//1.在内存中创建⼀张图⽚BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);//2.得到图⽚Graphics g = bi.getGraphics();//3.设置图⽚的背景⾊setBackGround(g);//4.设置图⽚的边框setBorder(g);//5.在图⽚上画⼲扰线int num = 5;//控制线条的数量drawRandomLine(g, num);//6.写在图⽚上的随机数int num2 = 4;//最多4个,这个地⽅可以通过调节输⼊框的宽度来进⾏调节//String random = drawRandomNum((Graphics2D) g,"ch");//⽣成中⽂验证码图⽚//String random = drawRandomNum((Graphics2D) g,"nl");//⽣成数字和字母组合的验证码图⽚//String random = drawRandomNum((Graphics2D) g,"n");//⽣成纯数字的验证码图⽚//String random = drawRandomNum((Graphics2D) g,"l");//⽣成纯字母的验证码图⽚String random = drawRandomNum((Graphics2D) g, num2, createTypeFlag);//7.将随机数写在session⾥⾯request.getSession().setAttribute("checkcode", random);//8.设置响应头通知浏览器以图⽚的⽅式打开response.setContentType("image/jpeg");//9.设置响应头控制浏览器不要缓存response.setDateHeader("expries", -1);response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-cache");//10.、把图⽚写进浏览器ImageIO.write(bi, "jpg", response.getOutputStream());}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}/****设置图⽚的背景⾊***/private void setBackGround(Graphics g) {//设置颜⾊g.setColor(Color.WHITE);//填充区域g.fillRect(0, 0, WIDTH, HEIGHT);}/***设置图⽚的边框**/private void setBorder(Graphics g) {g.setColor(Color.BLUE);g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);}/*****设置图⽚的随即线条******/private void drawRandomLine(Graphics g, int num) {g.setColor(Color.GREEN);//设置线条个数并划线for (int i = 0; i < num; i++) {int x1 = new Random().nextInt(WIDTH);int y1 = new Random().nextInt(HEIGHT);int x2 = new Random().nextInt(WIDTH);int y2 = new Random().nextInt(HEIGHT);g.drawLine(x1, y1, x2, y2);}}/*******画随机字符*******/private String drawRandomNum(Graphics2D g, int num, String...createTypeFlag) {g.setColor(Color.RED);g.setFont(new Font("宋体", Font.BOLD, 20));//常⽤的中国汉字String baseChineseChar = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u592 //数字和字母的组合String baseNumLetter = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ";//纯数字String baseNum = "0123456789";//纯字母String baseLetter = "ABCDEFGHJKLMNOPQRSTUVWXYZ";if (createTypeFlag.length > 0 && null != createTypeFlag[0]) {if (createTypeFlag[0].equals("ch")) {// 截取汉字return createRandomChar(g, baseChineseChar, num);} else if (createTypeFlag[0].equals("nl")) {// 截取数字和字母的组合return createRandomChar(g, baseNumLetter, num);} else if (createTypeFlag[0].equals("n")) {// 截取数字return createRandomChar(g, baseNum, num);} else if (createTypeFlag[0].equals("l")) {// 截取字母return createRandomChar(g, baseLetter, num);}} else {// 默认截取数字和字母的组合return createRandomChar(g, baseNumLetter,num);}return "";}/*** 创建随机字符**/private String createRandomChar(Graphics2D g, String baseChar, int num) {StringBuffer sb = new StringBuffer();int x = 5;String ch = "";//控制字数for (int i = 0; i < num; i++) {// 设置字体旋转⾓度int degree = new Random().nextInt() % 30;ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + "";sb.append(ch);// 正向⾓度g.rotate(degree * Math.PI / 180, x, 20);g.drawString(ch, x, 20);// 反向⾓度g.rotate(-degree * Math.PI / 180, x, 20);x += 30;}return sb.toString();}} ⽣成form表单的jsp页⾯:<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>验证码</title></head><body><form action="${pageContext.request.contextPath}/Response/ResoultServlet" method="post"><label for="yan">验证码</label><input type="text" name="yan" id="yan"><img src="${pageContext.request.contextPath}/Response/Response03" alt="验证码看不清,换⼀张" id="validateCodeImg" onclick="changeImg()"><a href="javascript:void(0)" onclick="changeImg()">看不清,换⼀张</a><input type="submit" value="提交"></form></body><script>function changeImg() {document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/Response/Response03?"+Math.random();//在末尾加Math.random()的作⽤:如果两次请求地址⼀样,服务器只会处理第⼀次请求,第⼆次请求返回内容和第⼀次⼀样。
随机验证码package com.itheima.test;/*1. 在登录注册页⾯中,除了⽤户名和密码外,通常也会包含验证码。
验证码是⽤来区分⽤户是计算机还是⼈,防⽌恶意破解密码、刷票、灌⽔等⾏为。
定义⽅法,获取⼀个包含4个字符的验证码,每⼀位字符是随机选择的字母和数字,可包含a-z,A-Z,0-9。
可以先⽤字符串准备⼀个包含所有字符的字符串:String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";*/import java.util.Random;import java.util.Scanner;public class String01 {public static void main(String[] args) {String randomCode = getRandomCode();System.out.println(randomCode);}//定义⽅法,返回值是String,参数列表为空。
public static String getRandomCode() {//定义StringBuilder对象,将可选择的字符都放到StringBuilder对象中。
StringBuilder stringBuilder = new StringBuilder();//定义循环从a-z,使⽤StringBuilder的append⽅法依次添加所有⼩写字母for (int i = 'a'; i <= 'z'; i++) {stringBuilder.append(i);}//定义循环从A-Z,使⽤StringBuilder的append⽅法依次添加所有⼤写字母for (int i = 'A'; i <= 'Z'; i++) {stringBuilder.append(i);}//定义循环从0-9,使⽤StringBuilder的append⽅法依次添加所有数字字符for (int i = '0'; i <= '9'; i++) {stringBuilder.append(i);}//创建Random对象Random random = new Random();//定义⼀个空字符串⽤于保存验证码String code = "";//定义⼀个执⾏4次的循环,⽤于获取4个字符for (int i = 0; i < 4; i++) {//在循环中,使⽤Random的nextInt⽅法,随机获取⼀个从索引0(包含)到字符串的长度(不包含)的索引 int anInt = random.nextInt(stringBuilder.length());// 使⽤StringBuilder的charAt⽅法,获取该索引上的字符,将其拼接到验证码字符串中code += stringBuilder.charAt(i);// 返回结果,并在主⽅法中调⽤⽅法查看结果。
SpringBoot使⽤Captcha⽣成验证码⽬录1. 基本结构2. Kaptcha的依赖3. 配置SpringBoot4. 配置Captcha5. ⼯具类6. 接⼝以及实现类7. Controller8. 前端页⾯的实现⽰例1. 基本结构使⽤Captcha⽣成验证码, 利⽤Redis存储验证码Redis中的结构为, Key是32位的UUID, Value为Captcha的4位随机字母以及数字的集合设定Redis过期时间为1min, 即可实现过期验证码的⾃动失效2. Kaptcha的依赖基本的依赖这⾥不再叙述, 主要说⼀下要导⼊Captcha的依赖<!--Kaptcha--><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>所有的依赖如下<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 https:///xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wang</groupId><artifactId>spring_security_framework</artifactId><version>0.0.1-SNAPSHOT</version><name>spring_security_framework</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!--Redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--JDBC--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--SpringSecurity--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--Thymeleaf--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--Validation--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!--SpringBoot Web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!--SpringSecurity with thymeleaf--><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency><!--MySQL connector--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--Lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--Test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency><!--Druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.2</version></dependency><!--FastJSON--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.74</version></dependency><!--log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!--Swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!--HuTool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.7</version></dependency><!--Kaptcha--><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>3. 配置SpringBoot配置SpringBoot的配置⽂件, 这⾥主要关注⼀个session的过期时间#Portserver:port: 80servlet:session:timeout: 1spring:application:name: SpringSecurityFramework#dataBase Settingdatasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource#Druid Settingdruid:initial-size: 5min-idle: 5max-active: 20max-wait: 60000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 30000validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: falsetest-on-return: falsepool-prepared-statements: true#Setting For Druid StatView and Filterfilters: stat,wall,log4jmax-pool-prepared-statement-per-connection-size: 20use-global-data-source-stat: trueconnection-properties: druid.stat.mergeSql=true;druid.stat.slowSql#Redis Settingredis:host: 127.0.0.1port: 6379#Thymeleafthymeleaf:cache: false#Mybatismybatis:type-aliases-package: com.wang.entitymapper-locations: classpath:Mybatis/mapper/*.xmlconfiguration:map-underscore-to-camel-case: true其余的配置, 如log4j, druid, SpringSecurity, RedisTemplate,这⾥就不再赘述4. 配置Captcha我们可以通过JAVA的配置类来配置Captcha⽣成验证码的⼀些规则package com.wang.spring_security_framework.config;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.google.code.kaptcha.util.Config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.Properties;//Kaptcha配置@Configurationpublic class KaptchaConfig {@Beanpublic DefaultKaptcha producer() {//Properties类Properties properties = new Properties();// 图⽚边框properties.setProperty("kaptcha.border", "yes");// 边框颜⾊properties.setProperty("kaptcha.border.color", "105,179,90");// 字体颜⾊properties.setProperty("kaptcha.textproducer.font.color", "blue");// 图⽚宽properties.setProperty("kaptcha.image.width", "110");// 图⽚⾼properties.setProperty("kaptcha.image.height", "40");// 字体⼤⼩properties.setProperty("kaptcha.textproducer.font.size", "30");// session keyproperties.setProperty("kaptcha.session.key", "code");// 验证码长度properties.setProperty("kaptcha.textproducer.char.length", "4");// 字体properties.setProperty("s", "宋体,楷体,微软雅⿊");//图⽚⼲扰properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.DefaultNoise");//Kaptcha 使⽤上述配置Config config = new Config(properties);//DefaultKaptcha对象使⽤上述配置, 并返回这个BeanDefaultKaptcha defaultKaptcha = new DefaultKaptcha();defaultKaptcha.setConfig(config);return defaultKaptcha;}}5. ⼯具类使⽤UUID作为key, 同时考虑到对验证码的输出结果可能有不同的要求, 这⾥写两个⼯具类来处理它们UUIDUtilpackage com.wang.spring_security_framework.util;import org.springframework.context.annotation.Bean;import ponent;import java.util.UUID;@Component public class UUIDUtil {/** * ⽣成32位的随机UUID * @return 字符形式的⼩写UUID */@Bean public String getUUID32() {return UUID.randomUUID().toString() .replace("-", "").toLowerCase();}}CaptchaUtilpackage com.wang.spring_security_framework.util;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.wang.spring_security_framework.service.CaptchaService;import ty.handler.codec.base64.Base64Encoder;import org.springframework.beans.factory.annotation.Autowired;import ponent;import sun.misc.BASE64Encoder;import javax.imageio.ImageIO;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Map;@Component//Captcha ⽣成⼯具public class CaptchaUtil {@Autowiredprivate DefaultKaptcha producer;@Autowiredprivate CaptchaService captchaService;//⽣成catchCreator的mappublic Map<String, Object> catchaImgCreator() throws IOException {//⽣成⽂字验证码String text = producer.createText();//⽣成⽂字对应的图⽚验证码BufferedImage image = producer.createImage(text);//将图⽚写出ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", outputStream);//对写出的字节数组进⾏Base64编码 ==> ⽤于传递8⽐特字节码BASE64Encoder encoder = new BASE64Encoder();//⽣成tokenMap<String, Object> token = captchaService.createToken(text);token.put("img", encoder.encode(outputStream.toByteArray()));return token;}}6. 接⼝以及实现类1. 接⼝package com.wang.spring_security_framework.service;import org.springframework.stereotype.Service;import java.io.IOException;import java.util.Map;public interface CaptchaService {//⽣成tokenMap<String, Object> createToken(String captcha);//⽣成captcha验证码Map<String, Object> captchaCreator() throws IOException;//验证输⼊的验证码是否正确String versifyCaptcha (String token, String inputCode);}2. 实现类package com.wang.spring_security_framework.service.serviceImpl;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.wang.spring_security_framework.service.CaptchaService; import com.wang.spring_security_framework.util.CaptchaUtil;import com.wang.spring_security_framework.util.UUIDUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.stereotype.Service;import java.io.IOException;import java.util.HashMap;import java.util.Map;import java.util.concurrent.TimeUnit;@Servicepublic class CaptchaServiceImpl implements CaptchaService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate UUIDUtil uuidUtil;@Autowiredprivate CaptchaUtil captchaUtil;//从SpringBoot的配置⽂件中取出过期时间@Value("${server.servlet.session.timeout}")private Integer timeout;//UUID为key, 验证码为Value放在Redis中@Overridepublic Map<String, Object> createToken(String captcha) {//⽣成⼀个tokenString key = uuidUtil.getUUID32();//⽣成验证码对应的token 以token为key 验证码为value存在redis中ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();valueOperations.set(key, captcha);//设置验证码过期时间redisTemplate.expire(key, timeout, TimeUnit.MINUTES);Map<String, Object> map = new HashMap<>();map.put("token", key);map.put("expire", timeout);return map;}//⽣成captcha验证码@Overridepublic Map<String, Object> captchaCreator() throws IOException {return captchaUtil.catchaImgCreator();}//验证输⼊的验证码是否正确@Overridepublic String versifyCaptcha(String token, String inputCode) {//根据前端传回的token在redis中找对应的valueValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();if (redisTemplate.hasKey(token)) {//验证通过, 删除对应的keyif (valueOperations.get(token).equals(inputCode)) {redisTemplate.delete(token);return "true";} else {return "false";}} else {return "false";}}}这⾥的验证, 只是简单的验证了输⼊是否能从Redis中匹配, 返回了字符串真实的验证中, 我们还要在逻辑中添加⽤户名和密码的考虑7. Controllerpackage com.wang.spring_security_framework.controller;import com.wang.spring_security_framework.service.CaptchaService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.io.IOException;import java.util.Map;@RestControllerpublic class LoginController {@AutowiredCaptchaService captchaService;@GetMapping("/captcha")public Map<String, Object> captcha() throws IOException {return captchaService.captchaCreator();}@GetMapping("/login1")public String login(@RequestParam("token") String token,@RequestParam("inputCode") String inputCode) {return captchaService.versifyCaptcha(token, inputCode);}}captcha ⽤于获取⼀个验证码login1 ⽤于接收到前端的请求后验证并返回结果login1 这⾥为了测试简便实⽤了GET⽅法, ⽽实际中最好使⽤POST⽅法, 这样安全性更⾼8. 前端页⾯的实现前端结构如图, 实现了⼀个简单的验证码<!DOCTYPE html><html lang="en" xmlns:th=""><head><meta charset="UTF-8"><title>登录</title><script src="https:///jquery/3.4.1/jquery.js"></script></head><body><div><div><form th:action="@{/login1}" method="get"><input type="text" id="userName" placeholder="请输⼊⽤户名" name="userName"><br><input type="password" id="password" placeholder="请输⼊密码" name="password"><br><input type="text" id="inputCode" placeholder="请输⼊验证码" maxlength="4" name="inputCode"><!--通过隐藏域传递值, 在下⾯的验证码点击事件中, 将值绑定过来, 这样就可以获得最新的验证码对应的值了!--><input id="token" value="" type="hidden" name="token"><input type="submit" value="登录"></form></div><div><!-- 当⽤户链接时,void(0)计算为0,⽤户点击不会发⽣任何效果 --><a href="javascript:void(0);" rel="external nofollow" title="点击更换验证码"><!--this参数, 返回当前的DOM元素--><img src="" alt="更换验证码" id="imgVerify" onclick="getVerify(this)"></a></div></div><script>//获得img对象let imgVerify = $("#imgVerify").get(0);//$(function())等同于$(document).ready(function()) ==> 页⾯加载完毕之后, 才执⾏函数$(function () {getVerify(imgVerify);});//onclick时间绑定的getVerify函数function getVerify(obj) {$.ajax({type: "GET",url: "/captcha",success: function (result) {obj.src = "data:image/jpeg;base64," + result.img;$("#token").val(result.token);}});}</script></body></html>⽤⼀个 a 标签包围 img 标签, 这样如果图⽚没有加载出来也有⼀个超链接, 不过点了以后没有效果(function())等同于(function())等同于(document).ready(function()) ==> 页⾯加载完毕之后, 才执⾏函数, 这⾥必须要写这个函数, 否则第⼀次加载不会调⽤ onclick ⽅法, 也就不会⽣成验证码!我们利⽤隐藏域将验证码的key传递到表单中, 我们在 img 的点击事件对应的函数的ajax回调函数中可以利⽤jQuery操作DOM, 顺带取出key值放到我们的隐藏域中, 这样提交的时候就会提交 key 和⽤户输⼊的 value 了⽰例验证通过以上就是SpringBoot使⽤Captcha⽣成验证码的详细内容,更多关于SpringBoot⽣成验证码的资料请关注其它相关⽂章!。
java随机验证码⽣成实现实例代码java随机验证码⽣成实现实例代码摘要: 在项⽬中有很多情况下都需要使⽤到随机验证码,这⾥提供⼀个java的随机验证码⽣成⽅案,可以指定难度,⽣成的验证码可以很⽅便的和其他组件搭配之前要使⽤⼀个⽣成随机验证码的功能,在⽹上找了⼀下,有很多的⼈提出了不同的解决⽅案,但是很多⼈都使⽤了com.sun.image.这个包或者⼦包⾥⾯的类,⽽这个包结构下⾯的类都是不推荐使⽤的,我们应该依赖于java.或者javax.这些包结构下⾯的类,否则将来的可移植性就很不好(⽐如换成IBM的JDK就不⾏了),但是还是有⼈没有⽤这些类也做成了的,所以我就在这些代码的基础上,修改了之后做成了下⾯的⼯具类,⼤家可以随意使⽤,同时也欢迎提出改进意见。
在jdk1.7.45运⾏通过。
⾸先是验证码⽣成,可以选择难度:package cn.songxinqiang.tool.util;import java.util.Arrays;public class RandomSecurityCode {/*** 验证码难度级别,Simple只包含数字,Medium包含数字和⼩写英⽂,Hard包含数字和⼤⼩写英⽂*/public enum SecurityCodeLevel {Simple, Medium, Hard};// 字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O)private final char[] CHAR_CODE = { '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y','z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L','M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };/*** 产⽣默认验证码,4位中等难度<br>* 调⽤此⽅法和调⽤getSecurityCode(4, SecurityCodeLevel.Medium, false)有⼀样的⾏为** @see #getSecurityCode(int, SecurityCodeLevel, boolean)* @return 验证码*/public char[] getSecurityCode() {return getSecurityCode(4, SecurityCodeLevel.Medium, false);}/*** 获取验证码,指定长度、难度、是否允许重复字符** @param length* 长度* @param level* 难度* @param isCanRepeat* 是否允许重复字符* @return 验证码*/public char[] getSecurityCode(int length, SecurityCodeLevel level,boolean isCanRepeat) {// 随机抽取len个字符int len = length;char[] code;// 根据不同的难度截取字符数组switch (level) {case Simple: {code = Arrays.copyOfRange(CHAR_CODE, 0, 9);break;}case Medium: {code = Arrays.copyOfRange(CHAR_CODE, 0, 33);break;}case Hard: {code = Arrays.copyOfRange(CHAR_CODE, 0, CHAR_CODE.length);break;}default: {code = Arrays.copyOfRange(CHAR_CODE, 0, CHAR_CODE.length);}}// 字符集合长度int n = code.length;// 抛出运⾏时异常if (len > n && isCanRepeat == false) {throw new RuntimeException(String.format("调⽤SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,"+ "当isCanRepeat为%3$s时,传⼊参数%1$s不能⼤于%4$s", len,level, isCanRepeat, n));}// 存放抽取出来的字符char[] result = new char[len];// 判断能否出现重复的字符if (isCanRepeat) {for (int i = 0; i < result.length; i++) {// 索引 0 and n-1int r = (int) (Math.random() * n);// 将result中的第i个元素设置为codes[r]存放的数值result[i] = code[r];}} else {for (int i = 0; i < result.length; i++) {// 索引 0 and n-1int r = (int) (Math.random() * n);// 将result中的第i个元素设置为codes[r]存放的数值result[i] = code[r];// 必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。
SpringBoot使用Captcha生成验证码验证码是一种用于验证用户身份的常见技术。
使用验证码可以防止恶意用户自动注册、暴力破解密码、刷票等攻击。
在Spring Boot中,我们可以使用Captcha库来生成验证码。
Captcha是一个Java库,用于生成图像验证码。
它可以生成不同类型的验证码,包括数字、字母、算术运算符等。
首先,我们需要在项目的pom.xml文件中添加Captcha库的依赖:```xml<dependency><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>```然后,在Spring Boot的配置文件中添加以下配置:```yamlkaptcha:border:color: blacktextproducer:char.length: 4image.width: 150image.height: 50```这些配置可以根据需求进行调整。
例如,可以更改验证码的字符集、长度、图像大小等。
接下来,在Spring Boot的控制器中添加生成验证码的方法:```javapublic void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException//创建验证码生成器DefaultKaptcha captchaProducer = new DefaultKaptcha(;//生成验证码文本String codeText = captchaProducer.createText(;// 将验证码文本保存到session中session.setAttribute("captcha", codeText);//创建验证码图像BufferedImage image = captchaProducer.createImage(codeText);//将图像输出到响应流中response.setContentType("image/jpeg");try (ServletOutputStream outputStream =response.getOutputStream()ImageIO.write(image, "jpeg", outputStream);}```在上面的方法中,我们使用DefaultKaptcha类来创建验证码生成器,并使用createText(方法生成验证码文本。
Java制作验证码的完整实例代码JAVA代码制作验证码,可⽤于注册等功能页⾯要导⼊servlet-api.jar包创建验证码的Util⼯具类:先创建图⽚并⽣成随机的验证码字母设置图⽚的底⾊,并⽤setFont函数将验证码画在图⽚上,如果想让验证码难⼀点,可以添加for循环的代码给图⽚增加旋转⾓度给验证码增加⼲扰线,提⾼安全性设置边框创建VerifyPic的servlet,通过Util类获取代码,并存⼊session中,然后输送去前端页⾯前端页⾯验证码如下:完整Util⼯具类代码如下:package com.sport.util;import java.awt.*;import java.awt.image.BufferedImage;import java.util.HashMap;import java.util.Map;public class VerifyUtil {public static Map<String, Object> generateVerify(){//创建⼀张图⽚BufferedImage verifyPic = new BufferedImage(120,40,BufferedImage.TYPE_3BYTE_BGR);//通过图⽚获取画笔Graphics2D g = verifyPic.createGraphics();//准备⼀个字母+数字的字典String letters = "23456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//规定验证码的位数int verifyLength = 4;//⽣成随机验证码String verifyCode = "";//循环取值for(int i=0; i<verifyLength; i++) {verifyCode +=letters.charAt((int)(Math.random()*letters.length()));}//将图⽚的底板由⿊变⽩g.setColor(Color.white);g.fillRect(0, 0, 120, 40);//将验证码画在图⽚之上g.setFont(new Font("微软雅⿊",Font.BOLD, 24));for (int i = 0; i < verifyLength; i++) {//随机产⽣⼀个⾓度double theta = Math.random() * Math.PI / 4 * ((int)(Math.random()*2) == 0?1:-1);//产⽣偏转g.rotate(theta, 24+i*22, 20);//每画⼀个字幕之前都随机给⼀个颜⾊g.setColor(new Color((int)(Math.random()*256), (int)(Math.random()*256), (int)(Math.random()*256)));g.drawString(verifyCode.charAt(i)+"", 20+i*22 , 26);//回正g.rotate(-theta, 24+i*22, 20);}//加⼊⼲扰线for (int i = 0; i < 5; i++) {//给随机颜⾊g.setColor(new Color((int)(Math.random()*256), (int)(Math.random()*256), (int)(Math.random()*256)));//画线g.drawLine((int)(Math.random()*120), (int)(Math.random()*40),(int)(Math.random()*120), (int)(Math.random()*40));}//设置边框颜⾊g.setColor(Color.black);//给验证码⼀个外边框g.drawRect(0, 0, 118, 38);//将验证码和图⽚⼀起存⼊mapMap<String, Object> data = new HashMap<String, Object>();data.put("verifyCode", verifyCode);data.put("verifyPic", verifyPic);return data;}}完整VerifyPic的代码如下:package com.sport.servlet;import com.sport.util.VerifyUtil;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Map;@WebServlet("/VerifyPic")public class VerifyPic extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Map<String, Object> data = VerifyUtil.generateVerify();//获取验证码String verifyCode = (String) data.get("verifyCode");//将验证码存⼊sessionHttpSession session = request.getSession();session.setAttribute("verifyCode", verifyCode);//获取图⽚BufferedImage verifyPic = (BufferedImage) data.get("verifyPic");//输出图⽚给前端,使⽤⼯具类ImageIOImageIO.write(verifyPic, "jpg", response.getOutputStream());}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}总结到此这篇关于Java制作验证码的完整实例代码的⽂章就介绍到这了,更多相关Java验证码完整代码内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
Java⽣成验证码原理(jsp)验证码的作⽤: 验证码是Completely Automated Public Turing test to tell Computers and Humans Apart(全⾃动区分计算机和⼈类的图灵测试)的缩写,是⼀种区分⽤户是计算机还是⼈的公共全⾃动程序,可以防⽌:恶意破解密码、刷票、论坛灌⽔、有效防⽌某个⿊客对某⼀特定注册⽤户,⽤特定程序暴⼒破解⽅式进⾏不断的登录尝试。
实际上验证码是现在很多⽹站通⾏的⽅式,我们利⽤⽐较简易的⽅式实现了这个功能。
第⼀代:标准验证码这⼀代验证码是即是我们常见的图形验证码、语⾳验证码,基于机器难以处理复杂的计算机视觉及语⾳识别问题,⽽⼈类却可以轻松的识别来区分⼈类及机器。
这⼀代验证码初步利⽤了⼈类知识容易解答,⽽计算机难以解答的机制进⾏⼈机判断。
下⾯这种验证码就是第⼀代Java 中⽣成验证码,⼀个.java就可以了ValidateCodeServlet.javapackage com.hpe.servlet;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/ValidateCodeServlet")public class ValidateCodeServlet extends HttpServlet {private static final long serialVersionUID = 1L;public ValidateCodeServlet() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 响应头信息response.setHeader("Pragma", "No-Cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expries", 0);// 随机数⽣成类Random random = new Random();// 定义验证码的位数int size = 5;// 定义变量保存⽣成的验证码String vCode = "";char c;// 产⽣验证码for (int i = 0; i < size; i++) {// 产⽣⼀个26以内的随机整数int number = random.nextInt(26);// 如果⽣成的是偶数,则随机⽣成⼀个数字if (number % 2 == 0) {c = (char) ('0' + (char) ((int) (Math.random() * 10)));// 如果⽣成的是奇数,则随机⽣成⼀个字母} else {c = (char) ((char) ((int) (Math.random() * 26)) + 'A');}vCode = vCode + c;}// 保存⽣成的5位验证码request.getSession().setAttribute("vCode", vCode);// 验证码图⽚的⽣成// 定义图⽚的宽度和⾼度int width = (int) Math.ceil(size * 20);int height = 50;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取图⽚的上下⽂Graphics gr = image.getGraphics();// 设定图⽚背景颜⾊gr.setColor(Color.WHITE);gr.fillRect(0, 0, width, height);// 设定图⽚边框gr.setColor(Color.GRAY);gr.drawRect(0, 0, width - 1, height - 1);// 画⼗条⼲扰线for (int i = 0; i < 5; i++) {int x1 = random.nextInt(width);int y1 = random.nextInt(height);int x2 = random.nextInt(width);int y2 = random.nextInt(height);gr.setColor(randomColor());gr.drawLine(x1, y1, x2, y2);}// 设置字体,画验证码gr.setColor(randomColor());gr.setFont(randomFont());gr.drawString(vCode, 10, 22);// 图像⽣效gr.dispose();// 输出到页⾯ImageIO.write(image, "JPEG", response.getOutputStream());}// ⽣成随机的颜⾊private Color randomColor() {int red = r.nextInt(150);int green = r.nextInt(150);int blue = r.nextInt(150);return new Color(red, green, blue);}private String[] fontNames = { "宋体", "华⽂楷体", "⿊体", "微软雅⿊", "楷体_GB2312" }; private Random r = new Random();// ⽣成随机的字体private Font randomFont() {int index = r.nextInt(fontNames.length);String fontName = fontNames[index];// ⽣成随机的字体名称int style = r.nextInt(4);int size = r.nextInt(3) + 24; // ⽣成随机字号, 24 ~ 28return new Font(fontName, style, size);}}直接运⾏Java⽣成的结果:在jsp⽹页上显⽰的效果:jsp代码:<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "/TR/html4/loose.dtd"> <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cache-Control" content="no-cache"><meta http-equiv="Expires" content="0"><title>login</title><link href="css/login.css" type="text/css" rel="stylesheet"><script type="text/javascript">function $(id){return document.getElementById(id);}function changeCode(){$("code").src = "ValidateCodeServlet?a="+new Date();}</script></head><body><div class="login"><div class="message">欢迎登录</div><hr class="hr15"><div id="darkbannerwrap"></div><form method="post"><input name="action" value="login" type="hidden"> <inputname="username" placeholder="⽤户名" required="" type="text"><hr class="hr15"><input name="password" placeholder="密码" required="" type="password"><hr class="hr15"><input name="check_code" placeholder="验证码" required="" type="text"style="width: 30%;"> <img class="img_code"src="ValidateCodeServlet" id="code" /> <a class="a_code"href="javascript:changeCode()">换⼀张</a><hr class="hr15"></form></div> </body> </html>。
java 验证码生成校验流程-回复生成和校验验证码是网络应用程序中常见的安全机制之一。
本文将详细介绍使用Java编程语言生成和校验验证码的流程,并提供一步一步的实现方法。
一、什么是验证码?验证码,全称为“全自动区分计算机和人类的公开图灵测试”,是一种用于确认用户是否为人类的技术。
它通常以图像或文字的形式显示,并要求用户正确地输入验证码以完成验证。
验证码的主要目的是防止恶意程序或机器人在网络应用程序中自动化执行任务,例如暴力破解密码或进行垃圾邮件的自动发送。
二、生成验证码的流程1. 定义验证码的属性:在Java中,我们可以定义一个验证码类,其中包含属性如宽度、高度、长度、字符类型等。
这些属性将在后续生成和校验过程中使用。
2. 生成随机字符序列:使用Java的随机数生成器,我们可以生成一个随机的字符序列作为验证码的内容。
可以根据需要定义字符的范围,例如数字、字母(大小写)、符号等。
3. 绘制验证码图像:使用Java的绘图工具,我们可以将随机生成的字符序列绘制为图像。
可以设置图像的宽度、高度、背景色、前景色等。
4. 输出图像:将绘制好的验证码图像输出到前端页面或保存为文件。
可以使用Java提供的图像输出库,例如Java 2D库或第三方库。
5. 存储验证码的值:为了进行验证码的校验,我们需要将生成的验证码值存储在后台。
可以将其存储在内存中、数据库中或客户端的会话中。
三、校验验证码的流程1. 获取用户输入的验证码:在前端页面上,用户需要输入验证码,并提交到后台进行校验。
可以使用HTML表单元素,例如输入框和提交按钮。
2. 从存储的位置获取验证码的值:通过之前存储的方式,我们可以从内存、数据库或会话中获取生成的验证码的值。
3. 比较用户输入的验证码和存储的验证码值:使用Java编程语言,我们可以将用户输入的验证码与存储的验证码值进行比较。
如果相等,则验证通过,否则验证失败。
4. 完成校验结果的反馈:根据校验结果,我们可以向用户反馈验证的结果。
JavaScript实现4位随机验证码的⽣成本⽂实例为⼤家分享了JavaScript⽣成4位随机验证码的具体代码,供⼤家参考,具体内容如下代码:<!doctype html><html><head><meta charset="utf-8"><title>4位随机验证码的⽣成</title><style>label{color:aqua;float:left;font-size: 20px;line-height:2em;}#tex{display:inline-block;width:50px;height: 25px;float:left;text-align: center;font-size:15px;margin-top:10px;}#showyz{border:3px solid green;color:blue;width:90px;height:40px;text-align:center;float:left;margin-left:15px;line-height: 2.5em;}#hyz{background-color:burlywood;border:1px solid burlywood;width:50px;height:20px;float: left;margin-left:20px;margin-top: 10px;margin-right:15px;}#btn{}</style></head><body><label for="tex">请输⼊验证码:</label><input type="text" id="tex" maxlength="4" autofocus><div id="showyz"></div><div id="hyz">换⼀张</div><br><input type="button" id="btn" value="确认"></body><script>//定义个空数组保存62个编码var codes=[];//将数字对应的编码保存到codes数组中,数字编码范围【48-57】for(var i=48;i<=57;i++){codes.push(i);}//将⼤写字母对应的编码保存到codes数组中,对应编码范围【65-90】for(var i=65;i<=90;i++){codes.push(i);}//将⼩写字母对应的编码保存到codes数组中,对应编码范围【97-122】for(var i=97;i<=122;i++){codes.push(i);}//定义个⽅法⽣成62位随机数作为数组⾓标返回随机的编码,再将其编码转化为对应数字或者字母function suiji(){var arr=[];//定义个数组保存4位随机数for(var i=0;i<4;i++){var index=Math.floor(Math.random()*(61-0+1)+0);//⽣成个随机数var char=String.fromCharCode(codes[index]);//解码arr.push(char); //存⼊到数组arr中}return arr.join("");//将数组转为字符串,以空格分隔,并返回}var yzm=suiji();//调⽤⽅法,将放回的验证码返回到yzm中//获取上述元素var tex=document.getElementById("tex");var showyz=document.getElementById("showyz");var hyz=document.getElementById("hyz");var btn=document.getElementById("btn");//将验证码写⼊到id为showyz的div中showyz.innerHTML=yzm;//实现换⼀张验证码功能hyz.οnclick=function(){yzm=suiji();showyz.innerHTML=yzm;}//将⾃⼰输⼊的验证码与获取的随机验证码验证btn.οnclick=function(){var textvalue=tex.value;//获取输⼊的值if(textvalue.toLowerCase()==yzm.toLowerCase()){//将值都转为⼩写⽐较alert("验证码输⼊正确!");yzm=suiji();showyz.innerHTML=yzm;tex.value="";}else{alert("验证码输⼊错误,请重新输⼊!");yzm=suiji();showyz.innerHTML=yzm;tex.value="";}}</script></html>以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
一、创建验证码,请准备好一张背景图片即噪点图片using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Drawing;public partial class CreateCode : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//创建验证码//1.生成四位随机字符串,可以是数字(ASCII码48-56)、大写字母(65-90)和小写字母(97-124)string code = "";Random r = new Random();while (code.Length < 4){int asciicode = r.Next(48, 125);char c = Convert.ToChar(asciicode);if (char.IsLetterOrDigit(c))code += c;}//2.获取噪点背景图片随便准备一张简单图片即可System.Drawing.Image bgImage = System.Drawing.Image.FromFile(Server.MapPath("Images\\validbg.jpg"));//3.绘制随机字符串Graphics g = Graphics.FromImage(bgImage);Font f = new Font("Courier New", 28);g.DrawString(code, f, Brushes.Black, new PointF(5, 5));Session["nowcode"] = code.ToLowerInvariant();//将当前产生的验证码存入Session中//4.输出Response.ContentType = "image/jpeg";bgImage.Save(Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg);bgImage.Dispose();Response.End();}}二、应用前台aspx页面1.刷新验证码<script type="text/javascript" language="javascript">function ReGetCode(item){$(item).attr('src','CheckCode.aspx?'+Math.random());}</script>或者<script type="text/javascript">//刷新验证码function reloadcode() {var verify = document.getElementById('thecheckcode');verify.setAttribute('src', 'CheckCode.aspx?' + Math.random());}</script><asp:TextBox ID="txtValidate" runat="server" Width="128px"></asp:TextBox><span onclick="ReGetCode(thecheckcode);" style="cursor:pointer"><img src="CheckCode.aspx?" id="thecheckcode" name="vercode" runat="server"/></span>2.cs页面if (Session["VerCode"] != null)//判断是否过期{if (txtValidate.Text.Trim() == Session["VerCode"].ToString().Trim())//判断是否输入正确{//验证码正确}else{Page.ClientScript.RegisterStartupScript(this.GetType(), "", "<script>alert('操作提示:验证码不正确!');</script>");}}else{Page.ClientScript.RegisterStartupScript(this.GetType(), "", "<script>alert('操作提示:验证码过期!');</script>");}。
java验证码的实现原理
Java验证码的实现原理是通过生成随机的字符串或数字,并将其显示在网页、移动应用或其他形式的用户界面上,以验证用户的真实性或防止机器人或自动化程序的恶意访问。
具体实现的步骤如下:
1. 生成随机字符串:使用Java的Random类等随机数生成器,生成指定长度的随机字符串。
可以使用字母、数字或符号组成字符串,根据需要进行自定义。
2. 存储验证码:将生成的验证码字符串存储在服务器端的某个变量或数据结构中,以备后续的验证操作。
3. 图片生成:使用Java的图形库(如AWT、Java 2D或第三
方库),将生成的验证码字符串绘制在图片上。
4. 图片展示:将生成的验证码图片通过HTTP请求返回给用户的浏览器或移动应用,供用户观看和输入。
5. 用户输入:用户通过输入设备(如键盘、鼠标或触摸屏)输入验证码字符串。
6. 验证:服务器端接收到用户输入的验证码字符串后,与之前存储的验证码进行比对。
如果一致,则验证通过;否则,验证失败。
验证码的实现原理主要依赖于服务器端生成随机字符串和图形库进行验证码图片的绘制。
通过将验证码字符串展示给用户,并要求用户输入该字符串,可以验证用户是否为人类或真实用户。
由于验证码每次生成都是随机的,机器人或自动化程序很难猜测或模拟生成验证码,从而有效地防止了恶意访问的行为。
怎么给验证码添加背景图片如何给验证码添加背景图片?有一段生成验证码的程序,想在背景上加上一副静态的图片,不知道该用什么方法。
请各位大侠指教!一下是生成验证码的程序:<%@ page contentType= "image/jpeg " import= "java.awt.*,java.awt.image.*,java.util.*,javax.imageio.* " %><%!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=60, height=20;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)); //画边框//g.setColor(new Color());//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 sRand= " ";for (int i=0;i <4;i++){String rand=String.valueOf(random.nextInt(10));sRand+=rand;// 将认证码显示到图象中g.setColor(newColor(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110))); //调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成g.drawString(rand,13*i+6,16);}// 将认证码存入SESSIONsession.setAttribute( "rand ",sRand);// 图象生效g.dispose();// 输出图象到页面ImageIO.write(image, "JPEG ", response.getOutputStream());。
java超经漂亮验证码 1package com.zly.xsp.image;23import java.awt.Color;4import java.awt.Font;5import java.awt.Graphics;6import java.awt.Graphics2D;7import java.awt.image.BufferedImage;8import java.io.IOException;9import java.io.OutputStream;10import java.util.Random;1112import javax.imageio.ImageIO;13import javax.servlet.http.HttpServletRequest;14import javax.servlet.http.HttpServletResponse;15import javax.servlet.http.HttpSession;1617public class CreateImageCode {18// 图⽚的宽度。
19private int width = 160;20// 图⽚的⾼度。
21private int height = 40;22// 验证码字符个数23private int codeCount = 4;24// 验证码⼲扰线数25private int lineCount = 20;26// 验证码27private String code = null;28// 验证码图⽚Buffer29private BufferedImage buffImg = null;30 Random random = new Random();3132public CreateImageCode() {33 creatImage();34 }3536public CreateImageCode(int width, int height) {37this.width = width;38this.height = height;39 creatImage();40 }4142public CreateImageCode(int width, int height, int codeCount) {43this.width = width;44this.height = height;45this.codeCount = codeCount;46 creatImage();47 }4849public CreateImageCode(int width, int height, int codeCount, int lineCount) {50this.width = width;51this.height = height;52this.codeCount = codeCount;53this.lineCount = lineCount;54 creatImage();55 }5657// ⽣成图⽚58private void creatImage() {59int fontWidth = width / codeCount;// 字体的宽度60int fontHeight = height - 5;// 字体的⾼度61int codeY = height - 8;6263// 图像buffer64 buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);65 Graphics g = buffImg.getGraphics();66//Graphics2D g = buffImg.createGraphics();67// 设置背景⾊68 g.setColor(getRandColor(200, 250));69 g.fillRect(0, 0, width, height);70717273// 设置字体74//Font font1 = getFont(fontHeight);75 Font font = new Font("Fixedsys", Font.BOLD, fontHeight);76 g.setFont(font);7778// 设置⼲扰线79for (int i = 0; i < lineCount; i++) {80int xs = random.nextInt(width);81int ys = random.nextInt(height);82int xe = xs + random.nextInt(width);83int ye = ys + random.nextInt(height);84 g.setColor(getRandColor(1, 255));85 g.drawLine(xs, ys, xe, ye);86 }8788// 添加噪点89float yawpRate = 0.01f;// 噪声率90int area = (int) (yawpRate * width * height);91for (int i = 0; i < area; i++) {92int x = random.nextInt(width);93int y = random.nextInt(height);9495 buffImg.setRGB(x, y, random.nextInt(255));96 }979899 String str1 = randomStr(codeCount);// 得到随机字符100this.code = str1;101for (int i = 0; i < codeCount; i++) {102 String strRand = str1.substring(i, i + 1);103 g.setColor(getRandColor(1, 255));104// g.drawString(a,x,y);105// a为要画出来的东西,x和y表⽰要画的东西最左侧字符的基线位于此图形上下⽂坐标系的 (x, y) 位置处106107 g.drawString(strRand, i*fontWidth+3, codeY);108 }109110111 }112113// 得到随机字符114private String randomStr(int n) {115 String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";116 String str2 = "";117int len = str1.length() - 1;118double r;119for (int i = 0; i < n; i++) {120 r = (Math.random()) * len;121 str2 = str2 + str1.charAt((int) r);122 }123return str2;124 }125126// 得到随机颜⾊127private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜⾊128if (fc > 255)129 fc = 255;130if (bc > 255)131 bc = 255;132int r = fc + random.nextInt(bc - fc);133int g = fc + random.nextInt(bc - fc);134int b = fc + random.nextInt(bc - fc);135return new Color(r, g, b);136 }137138/**139 * 产⽣随机字体140*/141private Font getFont(int size) {142 Random random = new Random();143 Font font[] = new Font[5];144 font[0] = new Font("Ravie", Font.PLAIN, size);145 font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);146 font[2] = new Font("Fixedsys", Font.PLAIN, size);147 font[3] = new Font("Wide Latin", Font.PLAIN, size);148 font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);149return font[random.nextInt(5)];150 }151152// 扭曲⽅法153private void shear(Graphics g, int w1, int h1, Color color) {154 shearX(g, w1, h1, color);155 shearY(g, w1, h1, color);156 }157158private void shearX(Graphics g, int w1, int h1, Color color) {159160int period = random.nextInt(2);161162boolean borderGap = true;163int frames = 1;164int phase = random.nextInt(2);165166for (int i = 0; i < h1; i++) {167double d = (double) (period >> 1)168 * Math.sin((double) i / (double) period169 + (6.2831853071795862D * (double) phase)170 / (double) frames);171 g.copyArea(0, i, w1, 1, (int) d, 0);172if (borderGap) {173 g.setColor(color);174 g.drawLine((int) d, i, 0, i);175 g.drawLine((int) d + w1, i, w1, i);176 }177 }178179 }180181private void shearY(Graphics g, int w1, int h1, Color color) {182183int period = random.nextInt(40) + 10; // 50;184185boolean borderGap = true;186int frames = 20;187int phase = 7;188for (int i = 0; i < w1; i++) {189double d = (double) (period >> 1)190 * Math.sin((double) i / (double) period191 + (6.2831853071795862D * (double) phase)192 / (double) frames);193 g.copyArea(i, 0, 1, h1, 0, (int) d);194if (borderGap) {195 g.setColor(color);196 g.drawLine(i, (int) d, i, 0);197 g.drawLine(i, (int) d + h1, i, h1);198 }199200 }201202 }203204205206public void write(OutputStream sos) throws IOException {207 ImageIO.write(buffImg, "png", sos);208 sos.close();209 }210211public BufferedImage getBuffImg() {212return buffImg;213 }214215public String getCode() {216return code.toLowerCase();217 }218219//使⽤⽅法220/*public void getCode3(HttpServletRequest req, HttpServletResponse response,HttpSession session) throws IOException{ 221 // 设置响应的类型格式为图⽚格式222 response.setContentType("image/jpeg");223 //禁⽌图像缓存。
使用JAVA生成四位随机验证码图片
效果:是第一位和第三位是随机数字,第二位和第四位是随机字母,图片中还有随机干扰线,这些数字,字母,干扰线的颜色均随机
package cn.itcast.web.response;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//生成验证码图片
public class Demo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
int WIDTH = 100;
int HIGHT = 30;
//在内在中创建一幅图片
BufferedImage image = new BufferedImage(WIDTH,HIGHT,BufferedImage.TYPE_INT_RGB); //取得一个画笔
Graphics g = image.getGraphics();
//设置字符串格式
g.setFont(new Font("黑体",Font.BOLD,24));
//画干扰线
for(int i=0;i<7;i++){
Random r = new Random();
int x1 = r.nextInt(WIDTH);
int x2 = r.nextInt(WIDTH);
int y1 = r.nextInt(HIGHT);
int y2 = r.nextInt(HIGHT);
Color color = new Color(
(new Double(Math.random() * 128)).intValue() + 128,
(new Double(Math.random() * 128)).intValue() + 128,
(new Double(Math.random() * 128)).intValue() + 128);
g.setColor(color);
g.drawLine(x1, y1, x2, y2);
}
//得到一个随机颜色
Color color = new Color(
(new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128);
g.setColor(color);
//画字符串
g.drawString(getVaule(), WIDTH/5, 2*HIGHT/3);
///flyzhouw
Color color1 = new Color(
(new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128);
g.setColor(color1);
g.drawString(getChar(), WIDTH/3, 2*HIGHT/3);
Color color2 = new Color(
(new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128);
g.setColor(color2);
g.drawString(getVaule(), WIDTH/2, 2*HIGHT/3);
Color color3 = new Color(
(new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128, (new Double(Math.random() * 128)).intValue() + 128);
g.setColor(color3);
g.drawString(getChar(), 2*WIDTH/3, 2*HIGHT/3);
//将内存中的图片,输出浏览器
ImageIO.write(image, "JPG", response.getOutputStream()); }
private String getVaule() {
Random r = new Random();
int num = r.nextInt(10);
return num + "";
}
private String getChar()
{
Random random =new Random();
int r = 0 ;
while(true)
{
r = random.nextInt(57) + 65;
if(r>90&&r<97||r==0)continue;
break;
}
char a = (char)r; return a + "";
}
}。