手撸简单验证码

2021-03-17 12:29:43 浏览数 (1)

验证机制是所有登录或关键业务都会用到的功能,验证机制也是多种多样,比如简单的验证码,语言验证码,短信验证码,还有一些根据行为进行验证的验证机制。这次我们来实现一个简单的验证码。

输出验证码的类

输出验证码是一个绘图的过程,绘图的过程大部分语言都是类似的,比如准备一个画布、准备一个画笔、然后在画布上绘制图形、输出内容等步骤。只是不同的语言具体调用的 API 不同而已。

直接上代码,代码如下:

代码语言:javascript复制

public class ImageCode
{
    // 图形中的内容
    private String code;

    // 图片
    private ByteArrayInputStream image;

    private int width = 400;
    private int height = 100;

    public static ImageCode getInstance() throws IOException {
        return new ImageCode();
    }

    private ImageCode() throws IOException
    {
        // 图形缓冲区 画布
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 画笔
        Graphics graphics = image.getGraphics();

        // 涂色
        graphics.setColor(new Color(255, 255, 255));
        // 画矩形
        graphics.fillRect(0, 0, width, height);
        // 字体
        graphics.setFont(new Font("宋体", Font.PLAIN, 30));

        Random random = new Random();

        this.code = "";

        StringBuilder sb = new StringBuilder(6);

        for (int i = 0; i < 6; i  ) {
            String s = String.valueOf(random.nextInt(10));

            sb.append(s);

            graphics.setColor(new Color(0, 0, 0));
            graphics.drawString(s, (width / 6) * i, 40);
        }

        this.code = sb.toString();

        // 收笔
        graphics.dispose();

        ByteArrayInputStream inputStream = null;
        ByteOutputStream outputStream = new ByteOutputStream();

        try {
            // 赋值给byteArrayInputStream
            ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream);
            ImageIO.write(image,"jpeg",imageOutputStream);

            inputStream = new ByteArrayInputStream(outputStream.toByteArray());

            imageOutputStream.close();
        }catch (Exception e){
            System.out.println("生成验证码失败");
        } finally {
            System.out.println("关闭资源");
            outputStream.close();
        }

        this.image = inputStream;

    }

}

输出验证码

上面的类就是一个用于输出验证码的类,我们要测试该类,需要创建一个 SpringMVC 的项目来进行测试,测试也比较简单,直接上代码,代码如下。

代码语言:javascript复制
@GetMapping("/verifyCode")
public void generatorCode(HttpServletResponse response){
    try {
        ImageCode imageCode = ImageCode.getInstance();

        // 验证码的值
        String code = imageCode.getCode();

        // 验证码图片
        ByteArrayInputStream image = imageCode.getImage();

        response.setContentType("image/jpeg");
        byte[] bytes = new byte[1024];
        try(ServletOutputStream out = response.getOutputStream()) {
            while (image.read(bytes) !=-1 ){
                out.write(bytes);
            }
        }
    }catch (Exception e){
        System.out.println("异常");
    }
}
    

上面的代码也是非常简单的,直接看效果吧。

上面就是验证码的输出,刷新一下可以看到数字又进行了变化。

总结

上面是一个简单的验证码,该验证码只是完成了简单的功能,在实际的场景中很容易被识别从而失去保护的作用。所以可以增加一些干扰线,或者对数字进行扭曲等变换。

0 人点赞