JAVA生成验证码,存放在redis做验证_java使用redistemplate保存登录验证码-程序员宅基地

技术标签: java  工作记录  redis  


import com.owinfo.utils.basetools.OwinfoStringUtil;
import org.springframework.data.redis.core.RedisTemplate;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 生成验证码
 */
public class CodeUtil {
    
    // 定义图片的width
    private static int width = 120;
    // 定义图片的height
    private static int height = 36;
    // 定义图片上显示验证码的个数
    private static int codeCount = 4;
    //字体之间的间距
    private static int xx = 20;
    private static int fontHeight = 28;
    //字体在y方向位置
    private static int codeY = 28;
    private static char[] codeSequence = {
    /*'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',*/ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 生成一个map集合
     * code为生成的验证码
     * codePic为生成的验证码BufferedImage对象
     *
     * @return 返回数据
     */
    public static Map<String, Object> generateCodeAndPic() {
    
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // Graphics2D gd = buffImg.createGraphics();
        // Graphics2D gd = (Graphics2D) buffImg.getGraphics();
        Graphics gd = buffImg.getGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        gd.setColor(Color.WHITE);
        //背景图中颜色位置
        gd.fillRect(0, 0, width, height);

        // 创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
        // 设置字体。
        gd.setFont(font);

        // 画边框。
        gd.setColor(Color.BLACK);
        //以下是设置边框的位置
        gd.drawRect(0, 0, width - 1, height - 1);

        // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
        gd.setColor(Color.black);
        for (int i = 0; i < 100; i++) {
    
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }

        // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;

        // 随机产生codeCount数字的验证码。
        for (int i = 0; i < codeCount; i++) {
    
            // 得到随机产生的验证码数字。
            String code = String.valueOf(codeSequence[random.nextInt(10)]);
            // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);

            // 用随机产生的颜色将验证码绘制到图像中。
            gd.setColor(new Color(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);

            // 将产生的四个随机数组合在一起。
            randomCode.append(code);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        //存放验证码
        map.put("code", randomCode);
        //存放生成的验证码BufferedImage对象
        map.put("codePic", buffImg);
        return map;
    }

    /**
     * 生成验证码的base64图片
     * 生成的验证码放入redis
     * @return map中有验证码的id 和图片base64
     */
    public static Map<String, String> getImg(RedisTemplate redisTemplate) throws Exception {
    
        Map<String, String> res = new HashMap<>(2);
        //创建文件输出流对象
        //OutputStream out = new FileOutputStream("E://img/" + System.currentTimeMillis() + ".jpg");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Map<String, Object> map = CodeUtil.generateCodeAndPic();
        ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", outputStream);
        Base64.Encoder encoder = Base64.getEncoder();
        String text = encoder.encodeToString(outputStream.toByteArray());
        String id = OwinfoStringUtil.createUUID();
        res.put("img", "data:image/png;base64," + text);
        res.put("imgId", id);
        redisTemplate.opsForValue().set("verification:" + id + map.get("code"), map.get("code"),600, TimeUnit.SECONDS);
        return res;
    }

    /**
     * 验证用户的验证码是否正确
     * @param redisTemplate redis服务
     * @param key 验证对应的id+用户输入的验证码
     * @return 验证结果
     */
    public static boolean checkVerification(RedisTemplate redisTemplate, String key) throws Exception {
    
        Object o = redisTemplate.opsForValue().get("verification:" + key);
        redisTemplate.delete("verification:" + key);
        return o == null;
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lq6812574/article/details/108998708

智能推荐

Python Django 安装(No module named setuptools)解决方案_离线安装django报错no module setuptools-程序员宅基地

文章浏览阅读2.6k次。只是在Windows环境下的解决方案。 使用Django做Python网站开发,按照官方步鄹引入的时候会出现如下错误。 这是因为需要引入一个第三方的模块,在Python的网站上面下载即可。(下载地址再图片的最下方) 链接地址:http://pypi.python.org/pypi/setuptools下载完成以后解压到自己存放的目录下,目录结构: 在此目录下执行如下命令:python set_离线安装django报错no module setuptools

IOS学习之页面之间的传值方式(Delegate/NSNotification/Block/NSUserDefault ,单例模式)_ios页面之间传值单例模式-程序员宅基地

文章浏览阅读434次。iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block) 实现了以下iOS页面间传值:1.委托delegate方式;2.通知notification方式;3.block方式;4.UserDefault或者文件方式;5.单例模式方式;6.通过设置属性,实现页面间传值 在iOS开发中,我们经常会遇到页面间跳转传值的问题,现归纳总结一下_ios页面之间传值单例模式

数据库系列课程(03)-Linux环境MyCat的安装与配置_mycat mber: 42; 必须为元素类型 "user" 声明属性 "defaultaccoun-程序员宅基地

文章浏览阅读486次。本文来讲解下如何在Linux下安装MyCat:1.上传Mycat-server-1.6.5-release-20180122220033-linux.tar2.解压安装包tar -zxvf Mycat-server-1.6.5-release-20180122220033-linux.tar.gz 3.配置schema.xmlcd /usr/local/mycat/conf/vi s..._mycat mber: 42; 必须为元素类型 "user" 声明属性 "defaultaccount"。

oracle 生成随机数语句,Oracle数据库生成随机数的函数-程序员宅基地

文章浏览阅读501次。在Oracle中的DBMS_RANDOM程序包中封装了一些生成随机数和随机字符串的函数,其中常用的有以下两个:DBMS_RANDOM.VALUE函数该函数用来产生一个随机数,有两种用法:1. 产生一个介于0和1之间(不包含0和1)的38位精度的随机数,语法为:DBMS_RANDOM.VALUE RETURN NUMBER;这种用法不包含参数。2. 产生一个介于指定范围之内的38位精度的随机数,语法..._oracle添加语句生成随机参数

Keep chatgpt alive, 安装插件,保持chatgpt在线_keepchatgpt下载-程序员宅基地

文章浏览阅读2.3k次。ChatGPT是一种基于自然语言处理(NLP)的人工智能技术,可以帮助我们实现智能聊天。然而,在使用ChatGPT插件过程中,我们可能会遇到频繁的网络错误,这会导致我们需要不断刷新网页,重复进行一些繁琐的操作,影响使用体验。为了解决这个问题,我们可以使用一些技巧来优化ChatGPT的使用过程,提高工作效率。_keepchatgpt下载

数据字典的理解_数据字典就是数据库表吗-程序员宅基地

文章浏览阅读6k次,点赞10次,收藏25次。数据字典的理解1.什么叫数据字典数据字典通俗上讲就是将数据抽象为字典的形式存储。想要理解数据字典首先我们要了解什么叫做字典,字典的构成,字典的作用,这些我们弄懂了基本上数据字典的概念大致也就弄懂了。从字典的构成理解:字典都是以键值对的方式来存储和查阅。所以数据字典必定也是以键值对的方式存储和查阅。假如我们不认识“任”这个字,想想我们使用字典查“任”这个字的时候首先查的是“亻”偏旁部首,然..._数据字典就是数据库表吗

随便推点

python中yield的用法详解——最简单,最清晰的解释_yield python-程序员宅基地

文章浏览阅读10w+次,点赞7.9k次,收藏9k次。首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受。接下来是正题:首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的,它首先是个return,普通的retur..._yield python

计算机网络开荒1-概述-程序员宅基地

文章浏览阅读823次。计算机网络 = 通信技术 + 计算机技术计算机网络定义:计算机网络就是互联的、自治的计算机集合自治-无主从关系互联-互联互通。

iOS端屏幕录制开发指南_oc 调用屏幕录制全局-程序员宅基地

文章浏览阅读1.4k次。一、 概述实现直播过程中共享屏幕分为两个步骤:屏幕数据采集和流媒体数据推送。前对于 iOS 来说,屏幕采集需要系统的权限,受制于iOS系统的限制,第三方 app 并没有直接录制屏幕的权限,必须通过系统的功能来实现。本文将描述iOS系统的屏幕共享的应用、实现、限制、实现细节等方面调研结果。(注:由于iOS 10和之前的系统只支持App内录制屏幕,所以只做简单的介绍,不做详细说明)二、 应用屏幕共享早起出现在视频会议当中,后来在一些游戏直播中也出现了大规模应用,Apple早期不支持屏幕共享,但随着直播的_oc 调用屏幕录制全局

CLion开发图书管理系统项目 (c++ + MySQL实现)_c++编写图书管理系统mysql-程序员宅基地

文章浏览阅读1k次,点赞3次,收藏15次。当下市场日益激烈的竞争迫使图书企业采用一种新的管理方式来加快图书管理操作,而计算机技术的发展为图书管理注入了新的生机。通过调查市场,一款合格的图书管理系统必须具备以下三个特点:能够对图书信息进行集中管理、能够大大提高用户工作效率、能够对图书的部分信息进行查询 基于上述需求,笔者在此开发出一款简单的图书管理系统以方便用户管理图书信息。_c++编写图书管理系统mysql

UVa 11504 - Dominos_11518 - dominos 2 python-程序员宅基地

文章浏览阅读1.8k次。题目:有一些多米诺骨牌,现在告诉你他们的相邻顺序,问最少推几次可以把他们全部推倒。分析:图论,强连通分量。强连通分量上的某点被推到,整个分量都会倒。 求强连通分量,然后缩点,剩下的“点”中每个入度为0的点都要用手推倒;(必要性) 再者,在缩点后的图中,每次找到一个入度为0的点推倒后,不会产生新的入度为0的点;(充分性) _11518 - dominos 2 python

IE6的一些兼容性问题-程序员宅基地

文章浏览阅读295次。总结一下IE6兼容性的部分小问题: 1.IE6的hack问题:在css属性前加上下划线“_”,这个属性就是IE6认识的专有属性。可以用它解决一些IE6的兼容问题。 例如:_background-color:red;//只有IE6才认识这个属性2.IE6不支持小于12px的盒子。解决办法是给盒子设置一个“_font-size”属性,使属性值尽可能小,如:_font-size:0;div{