【验证码】使用Java生成验证码,随机生成的长度不少于4位的字符,应包含字母与数字,并在显示时对其进行扭曲处理,提高识别的难度

  • 作者: 凯哥Java(公众号:凯哥Java)
  • 工作小总结
  • 时间:2023-06-12 11:33
  • 2154人已阅读
简介 需求:随机生成的长度不少于4位的字符,应包含字母与数字,并在显示时对其进行扭曲处理,提高识别的难度效果:这是上一篇文章中介绍的方案,但是,这种验证码过于简单。不能满足需求,修改后效果如下:完整代码:import javax.imageio.ImageIO;import java.awt.*;import java.awt.geom.AffineTransform;im

🔔🔔🔔好消息!好消息!🔔🔔🔔

有需要的朋友👉:联系凯哥 微信号 kaigejava2022


需求:

随机生成的长度不少于4位的字符,应包含字母与数字,并在显示时对其进行扭曲处理,提高识别的难度

效果:

a947cc223d3646b87631b0c02d1d1498.png

这是上一篇文章中介绍的方案,但是,这种验证码过于简单。不能满足需求,修改后效果如下:

a31893b1c47d88f92099c714ab8d59ef.png

完整代码:

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;

public class DistortedText {
    public static void main(String[] args) {
        int width = 200;
        int height = 80;
        int codeLength = 4;
        String randomString = generateRandomString(codeLength);
        String filename = "distorted_text.png";
        drawDistortedText(width, height, randomString, filename);
    }

    private static String generateRandomString(int length) {
        String lettersAndDigits = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        SecureRandom random = new SecureRandom();
        for (int i = 0; i < length; i++) {
            sb.append(lettersAndDigits.charAt(random.nextInt(lettersAndDigits.length())));
        }
        return sb.toString();
    }

    private static void drawDistortedText(int width, int height, String text, String filename) {
        SecureRandom random = new SecureRandom();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();

        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 填充背景颜色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        Font font = new Font("Arial", Font.BOLD, 28);
        g2d.setFont(font);

        int fontSize = font.getSize();
        int charWidth = width / text.length();

        // 绘制字符串,并进行扭曲
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);

            // 随机颜色
            Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
            g2d.setColor(color);

            // 扭曲变换
            double angle = random.nextInt(60) - 30;
            double x = i * charWidth + charWidth / 2.0;
            double y = height / 2.0 + fontSize / 2.0 - 10;
            AffineTransform transform = AffineTransform.getRotateInstance(Math.toRadians(angle), x, y);
            g2d.setTransform(transform);

            g2d.drawChars(new char[]{c}, 0, 1, (int) x, (int) y);
            g2d.setTransform(new AffineTransform());
        }

        // 添加随机干扰线
        g2d.setColor(Color.GRAY);
        for (int i = 0; i < 4; i++) {
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g2d.drawLine(x1, y1, x2, y2);
        }

        // 添加随机噪点
        float noiseDensity = 0.05f;
        int numPixels = (int)(noiseDensity * width * height);
        for (int i = 0; i < numPixels; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int rgb = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)).getRGB();
            image.setRGB(x, y, rgb);
        }

        // 保存为文件
        try {
            ImageIO.write(image, "png", new File(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

本文相当于上一篇,做的修改如下:

它使用多个扭曲变换和随机颜色进行绘制来增加验证码的难度。上述代码中,我们为每个字符设置了不同的颜色,并使用多个不同的旋转角度进行扭曲变换。我们还添加了随机的干扰线和噪点来提高

TopTop