几种生成验证码的方式以及计算表达式的计算

2023-10-27

kaptcha 数字字母形式验证码

google kaptcha验证码生成器且可以配置生成的验证码格式

引入依赖:

<dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>kaptcha</artifactId>
    <version>0.0.9</version>
</dependency>

配置生成验证码格式

 

@Slf4j
@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha defaultKaptcha() {
        DefaultKaptcha kaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        //是否有边框  默认为true  我们可以自己设置yes,no
        properties.setProperty(Constants.KAPTCHA_BORDER, "no");
        // 边框颜色
        properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "220,220,220");
        //验证码文本字符大小
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "5");
        // 验证码图片宽度
        properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "147");
        // 验证码图片高度
        properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "34");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "25");
        properties.setProperty(Constants.KAPTCHA_SESSION_KEY, "code");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
        properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "164,128,55");
        properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");
        //config属性
        Config config = new Config(properties);
        kaptcha.setConfig(config);
        return kaptcha;
    }
}

 

测试:

@RestController
@RequestMapping("/kaptcha")
public class KaptChaController {


    @Autowired
    @Qualifier("defaultKaptcha")
    private DefaultKaptcha producer;

    @ApiOperation("图片验证码")
    @RequestMapping(value = "/captcha.jpg",method = RequestMethod.GET)
    public void captcha(HttpServletResponse response)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        //生成文字验证码
        String text = producer.createText();
        producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
    }

}

表达式验证码

另外一种验证码生成格式是用户自定义配置生成的验证码,可以是表达式验证码

引入依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>kaptcha-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>

接口:

 

@RequestMapping("/kcaptcha")
public class KcaptchaController {

    @Autowired
    private Kaptcha kaptcha;

    @ApiOperation("登录 验证, 这里只需要判断验证码是否正确")
    @RequestMapping("/login")
    public Object login(String verifyCode, HttpServletRequest request) {
        try {
            final boolean result = kaptcha.validate(verifyCode, 60);
            if (result) {
                return "success";
            } else {
                return null;
            }
        } catch (KaptchaIncorrectException e) {
            return null;
        }
    }

    @ApiOperation("用来产生验证码")
    @RequestMapping("/verifyCode")
    public void generateImage(HttpServletRequest request, HttpServletResponse response) throws IOException {

        final ImageUtil imageUtil = ImageUtil.getInstance();
        //验证码图片
        final ByteArrayInputStream image = imageUtil.getImage();
        //验证码文字
        final String verifyCode = imageUtil.getStr();
        request.getSession().setAttribute("verifyCode",verifyCode);

        response.setContentType("image/jpeg");
        byte[] bytes = new byte[1024];
        try(final ServletOutputStream out = response.getOutputStream()){
            while (image.read(bytes)!= -1 ){
                out.write(bytes);
            }
        }
    }
}
@Slf4j
public class ImageUtil {

    /**验证码*/
    private String str ;
    /**验证码图片*/
    private ByteArrayInputStream image ;
    /**图片宽度*/
    private int width = 350; 
    /**图片高度*/
    private int height = 46; 

    private ImageUtil(){
        init();
    }

    public static ImageUtil getInstance(){
        return new ImageUtil();
    };

    private void init(){
        this.str= "";

        final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        final 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,20));

        g.setColor(getRandColor(160,200));
        for(int i = 0 ; i < 150 ; i ++){
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(50);
            int y1 = random.nextInt(50);
            g.drawLine(x,y,x+x1,y+y1);
        }

//        for(int i = 0 ; i < 6 ; i ++){
//            final String rand = String.valueOf(random.nextInt(10));
//            this.str += rand;
//            g.setColor(getRandColor(20,110));
//            g.drawString(rand,(width / 6)*i,46);
//        }

        int num1 = random.nextInt(10);
        int num2 = random.nextInt(10);
        g.setColor(getRandColor(20,110));
        g.drawString(String.valueOf(num1),(width/5)*0+6,36);
        g.drawString("+",(width/5)*1+6,36);
        g.drawString(String.valueOf(num2),(width/5)*2+6,36);
        g.drawString("=",(width/5)*3+6,36);
        g.drawString("?",(width/5)*4+6,36);

        this.str = String.valueOf(num1+num2);

        g.dispose();
        ByteArrayInputStream inputStream = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try{
            final ImageOutputStream imageOut = ImageIO.createImageOutputStream(outputStream);
            ImageIO.write(image,"JPEG",imageOut);
            imageOut.close();
            inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        }catch (Exception e){
            System.out.println("验证码图片生成失败:"+e);
        }
        this.image = inputStream;
    }

    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);
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    public ByteArrayInputStream getImage() {
        return image;
    }

    public void setImage(ByteArrayInputStream image) {
        this.image = image;
    }
}

 

这种形式的验证码在验证的时候需要对生成的表达式验证码进行计算并结合用户输入的结果进行比对来校验结果

 

下面介绍几种表达式计算工具

javax script表达式计算

首先介绍下java自带的表达式计算工具包:javax.script

写一个demo 看下使用

public class JavaxscriptTest {

    private static char[] ops = new char[]{'+', '-', '*'};


    private static String generateVerifyCode(Random rdm) {
        int num1 = rdm.nextInt(10);
        int num2 = rdm.nextInt(10);
        int num3 = rdm.nextInt(10);
        char op1 = ops[rdm.nextInt(3)];
        char op2 = ops[rdm.nextInt(3)];
        String exp = "" + num1 + op1 + num2 + op2 + num3;
        return exp;
    }


    private static Integer calc(String exp) {
        try {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            return (Integer) engine.eval(exp);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        String express = generateVerifyCode(new Random());
        log.info("生成的表达式:{}", express);

        log.info("表达式计算结果:{}", calc(express));

    }
}

输出结果:

14:58:30.047 [main] INFO com.fariy.kaptcha.express.util.JavaxscriptTest - 生成的表达式:3+2-9
14:58:31.103 [main] INFO com.fariy.kaptcha.express.util.JavaxscriptTest - 表达式计算结果:-4

这种生成的表达式是随机生成的,主要方法是:

 engine.eval(exp); 计算表达式结果

再来看另外一个表达式计算

common-jexl3

引入依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl3</artifactId>
    <version>3.1</version>
</dependency>

如果结合 表达式模型来计算 再引入依赖

<dependency>
    <groupId>org.xidea</groupId>
    <artifactId>jsel</artifactId>
    <version>0.1.0</version>
</dependency>

 

demo案例:

public static void test1() {
    JexlContext jexlContext = new MapContext();
    jexlContext.set("var1", 1);
    jexlContext.set("var2", 2);

    JexlBuilder builder = new JexlBuilder();
    JexlExpression expression = builder.create().createExpression("var1 + 2 * var2");

    Object evaluate = expression.evaluate(jexlContext);

    log.info("evaluate :{} ", evaluate);
}


public static void test2() {
    Expression el = new ExpressionImpl("var1 + 2 * var2");
    HashMap context = new HashMap();

    context.put("var1", 111);
    context.put("var2", 2);

    Object evaluate = el.evaluate(context);

    log.info("evaluate :{} ", evaluate);
    log.info("var1 :{} ", context.get("var1"));
    log.info("var2 :{} ", context.get("var2"));

    context.put("var2", 3);

    log.info("var1 :{} ", context.get("var1"));
    log.info("var2 :{} ", context.get("var2"));
    log.info("evaluate2 :{} ", el.evaluate(context));
}

public static void main(String[] args) {
    test2();

}

这一种表达式可以根据表达式计算模型传参进行计算,也可以对复杂嵌套结构进行计算

aviator计算

引入依赖

<dependency>
    <groupId>com.googlecode.aviator</groupId>
    <artifactId>aviator</artifactId>
    <version>5.3.0</version>
</dependency>

demo:

public static void test1() {
    //数字型计算
    log.info("数字计算:{}", AviatorEvaluator.execute("1.22+2.32+3"));
    //字符型计算
    String exp1 = "'Hello '+ name";
    Map<String, Object> env1 = new HashMap<>();
    env1.put("name", "tony");
    log.info("字符型计算:{}", AviatorEvaluator.execute(exp1, env1));
    //判断型计算
    String exp2 = "a+b>c";
    Map<String, Object> env2 = new HashMap<>();
    env2.put("a", 5);
    env2.put("b", 6);
    env2.put("c", 7);
    log.info("判断型计算:{}", AviatorEvaluator.execute(exp2, env2));
}


public static void main(String[] args) {
    test1();

}

测试输出:

15:04:40.776 [main] INFO com.fariy.kaptcha.express.util.AviatorTest - 数字计算:6.54
15:04:40.783 [main] INFO com.fariy.kaptcha.express.util.AviatorTest - 字符型计算:Hello tony
15:04:40.784 [main] INFO com.fariy.kaptcha.express.util.AviatorTest - 判断型计算:true

Aviator支持三种类型计算:Boolean,字符串,和数字类型,可以发现Aviator 涵盖了表达式计算以及格式匹配替换,相对来说使用范围广泛

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

几种生成验证码的方式以及计算表达式的计算 的相关文章

随机推荐

  • jieba textrank关键词提取 python_五款中文分词工具在线PK: Jieba, SnowNLP, PkuSeg,THULAC, HanLP...

    最近玩公众号会话停不下来 玩转腾讯词向量 Game of Words 词语的加减游戏 准备把NLP相关的模块搬到线上 准确的说 搬到AINLP公众号后台对话 所以 趁着劳动节假期 给AINLP公众号后台聊天机器人添加了一项新技能 中文分词线
  • 使用plist创建精灵并执行动画

    素材图 然后使用Texture Packer放到一张图片上 并生成plist文件 接下来直接上代码 CCSize size CCDirector sharedDirector gt getWinSize 获得屏幕的尺寸 CCArray pA
  • Js中var,let,const的区别

    一 区别 1 var声明的变量属于函数作用域 而let和const声明的变量属于块级作用域 js作用域在上篇文章 2 var声明的变量存在变量提升 而let和const没有 3 var声明的变量可以重复声明 而在同一块级作用域 let变量不
  • 关于加速

    对于下面的式子 我们可以直接枚举d 1 x 那么就会有x d个f d 相乘就会得到答案 但是有时候这样处理还是会慢 该如何解决呢 我们可以举个例子 x 6 d 1 x d 6 d 2 x d 3 d 3 x d 2 d 4 x d 1 d
  • vue中怎么配置@路径

    首先vite去创建项目 然后在vite conflg js文件中去配置 import defineConfig from vite import vue from vitejs plugin vue 引入path模块 import path
  • 低通滤波-matlab低通滤波程序

    本例程展示了信号处理中低通滤波的作用 首先生成一个高斯白噪声 然后对其进行低通滤波 低通滤波器的截止频率和Q值可以自己设定 得到低通滤波器的传输函数后 在经过双线性变换法得到其单位脉冲响应 滤波后对原始信号的频谱和滤波后的信号的频谱进行了对
  • docker安装指定版本mysql

    搜索mysql docker search mysql 具体查看mysql镜像版本 https hub docker com mysql tab tags 安装版本 docker pull mysql 5 7 默认安装 docker pul
  • el-table 超出隐藏,悬浮提示

  • makefile自动化变量及其说明

    模式规则 模式规则类似于普通规则 只是在模式规则中 目标名中需要包含有模式字符 一个 包含有模式字符 的目标被用来匹配一个文件名 可以匹配任何非空字符串 规则的依赖文件中同样可以使用 依赖文件中模式字符 的取值情况由目标中的 来决定 例如
  • C语言静态库、动态库的封装和注意事项

    1 动态库 静态库介绍 参考博客 静态库和动态库介绍以及Makefile 2 代码目录结构和编译脚本 参考博客 实际工作开发中C语言工程的目录结构分析 3 编写库的流程 1 明确需求 需求是否合理 需求的使用场景 需求可能遇到的出错情况 2
  • 安装.NetFramework4.7.2

    1 下载安装包 下载路径 https support microsoft com en us topic microsoft net framework 4 7 2 offline installer for windows 05a7273
  • MySQL学习(6)SHOW,USER

    1 SELECT USER 获得当前登陆用户的用户名与主机信息 使用该命令会显示类似于如下信息 root zxj lest vicp cc 前面是用户名 后面是主机名 2 SHOW用法 SHOW DATABASES 显示多少个数据库 也可以
  • CentOS 升级 OpenSSL 至最新版教程

    文章目录 一 服务器环境 二 升级b步骤 2 1 下载最新版的 OpenSSL 2 2 编译并安装 2 3 链接 libssl 2 4 备份旧的并启用新的 OpenSSL 2 5 检查 OpenSSL 版本 一 服务器环境 CentOS 版
  • Shuffle Net系列【V1—V2】

    1 ShuffleNet V1 1 1 Abstract 我们提出了一个极其效率的CNN架构 ShuffleNet 其专为计算能力非常有限的移动设备设计 这个新的架构利用了两个新的操作 pointwise group conv和channe
  • 数据结构 算法 进阶篇

    如果说计算机的出现推动了现代科技的发展 那么算法的出现则扩大了现代计算机的应用范围 硬件是计算机的基础 而算法则是计算机的灵魂 作为一名计算机爱好者 程序员抑或计算机科学家 如果不了解算法 就不能更好地理解和使用计算机 著名的计算机科学家尼
  • 一个XSS靶场练习记录

    首先 传送门 http xss fbisb com yx level1 php name test 其次 挑选合适的浏览器 我用的火狐 Chrome会阻断掉你的XSS注入 level1 产看下源码 ctrl u
  • 近期学习7.17

    操作平台 九天毕昇九天 毕昇 10086 cn 创建实例 try 配置 NVIDIA V100 虚拟化 CPU 2核 内存 16G 创建虚拟环境 conda create n try python 3 8 默认3 8 17 部署chatgl
  • #pragma预处理命令

    pragma可以说是C 中最复杂的预处理指令了 下面是最常用的几个 pragma指令 pragma comment lib XXX lib 表示链接XXX lib这个库 和在工程设置里写上XXX lib的效果一样 pragma commen
  • 用 Python+AI 让小朋友的手绘图跳起来(附完整源码)

    大家好 今天给大家介绍一个非常有趣的项目 基于AI识别 制作儿童手绘图舞蹈图 只需几分钟 就能自动生成儿童手绘人物或类人角色 即具有双臂 两条腿等的角色 的动画 而且生成的动画还能做到栩栩如生 不仅可以跳舞 还能打跆拳道 空中飞踢 模拟人的
  • 几种生成验证码的方式以及计算表达式的计算

    kaptcha 数字字母形式验证码 google kaptcha验证码生成器且可以配置生成的验证码格式 引入依赖