滑块验证码破解----Java使用opencv后端破解滑块验证

使用技术:Java + SpringBoot+openCV

在windows上首先需要下载opencv进行安装,先去官网:Releases - OpenCV 下载这个windows版本的安装包

下载后直接安装解压就行,然后需要,然后找到安装位置里的这个文件:

你下载的是什么版本的,这里的数字就是多少,比如我下载4.5.3版本那么这里就是453,下载4.9.0这里就显示490

这个文件是外部库,在使用opencv的时候需要用到这个文件

代码:

图片工具类:
import cn.hutool.core.io.IoUtil;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Base64;
import java.util.UUID;


/**
 * 图片工具
 *
 * @author Jerry
 * @date 2024/04/17
 */
@Component
public class PictureUtil {
    /**
     * opencv库的dll路径    todo 需要改成自己的
     */
    public static final String dllPath = "J:/opencv/opencv/build/java/x64/opencv_java453.dll";

    /**
     * 保存临时文件的路径
     */
    public static final String savePath = "D:/pngtemp";
    /**
     * png文件后缀
     */
    public static final String pngFileSuffix = ".png";

    static {
        //加载
        System.load(dllPath);

    }


    /**
     * 通过opencv库获取验证码需要移动的距离  获取横坐标
     *
     * @param bUrlBase64 b 大图片的base64
     * @param sUrlBase64 s 小图片的base64
     * @return double
     */
    public static double getDistanceByBase64ByOpenCv(String bUrlBase64, String sUrlBase64) {
        // 读取背景图
        String bFilePath = base64ToPNG(bUrlBase64);
        Mat background = Imgcodecs.imread(bFilePath);
        // 读取滑块图
        String sFilePath = base64ToPNG(sUrlBase64);
        Mat slider = Imgcodecs.imread(sFilePath);

        // 使用模板匹配来找到滑块在背景图中的位置
        Mat result = new Mat();
        Imgproc.matchTemplate(background, slider, result, Imgproc.TM_CCOEFF_NORMED);

        Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
        Point matchLoc = mmr.maxLoc;
        //删除临时文件
        deleteFile(bFilePath, sFilePath);
        return matchLoc.x;
    }

    /**
     * 删除文件
     *
     * @param bFilePath b文件路径
     */
    public static void deleteFile(String... bFilePath) {
        for (String path : bFilePath) {
            try {
                new File(path).delete();
            } catch (Exception ignored) {
            }
        }

    }

    /**
     * 将base64转为图片
     *
     * @param base64String base64字符串
     */
    public static String base64ToPNG(String base64String) {
        //文件名
        String outputFileName = savePath + "/" + UUID.randomUUID().toString() + pngFileSuffix;
        ByteArrayInputStream bis = null;
        OutputStream os = null;
        try {
            // 解码base64数据
            byte[] decodedBytes = Base64.getDecoder().decode(base64String);

            // 将解码后的数据转换为图像
            bis = new ByteArrayInputStream(decodedBytes);
            BufferedImage image = ImageIO.read(bis);

            // 将图像保存为PNG文件
            os = new FileOutputStream(outputFileName);
            ImageIO.write(image, "png", os);

            bis.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            IoUtil.close(bis);
            IoUtil.close(os);
        }
        return outputFileName;
    }

    /**
     * 只删开头
     *
     * @param str str
     * @return {@link String}
     */
    public static String substringBase64OnlyBegin(String str) {
        return str.substring(str.indexOf(",") + 1);
    }


    public static int findSliderPosition(String bUrlBase64, String sUrlBase64) {
        BufferedImage background = base64ToBufferedImage(bUrlBase64);
        BufferedImage slider = base64ToBufferedImage(sUrlBase64);
        ;


        double minDiff = Double.MAX_VALUE;
        int sliderXCoordinate = 0;

        for (int x = 0; x < background.getWidth() - slider.getWidth(); x++) {
            double diff = 0;
            for (int i = 0; i < slider.getWidth(); i++) {
                for (int j = 0; j < slider.getHeight(); j++) {
                    int rgb1 = background.getRGB(x + i, j);
                    int rgb2 = slider.getRGB(i, j);
                    int r1 = (rgb1 >> 16) & 0xFF;
                    int g1 = (rgb1 >> 8) & 0xFF;
                    int b1 = (rgb1 & 0xFF);
                    int r2 = (rgb2 >> 16) & 0xFF;
                    int g2 = (rgb2 >> 8) & 0xFF;
                    int b2 = (rgb2 & 0xFF);
                    diff += Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2);
                }
            }
            diff /= (slider.getWidth() * slider.getHeight());
            if (diff < minDiff) {
                minDiff = diff;
                sliderXCoordinate = x;
            }
        }
        return sliderXCoordinate;
    }

    /**
     * base64到缓冲图像
     *
     * @param base64str base64str
     * @return {@link BufferedImage}
     */
    private static BufferedImage base64ToBufferedImage(String base64str) {
        try {
            byte[] imageBytes = Base64.getDecoder().decode(base64str);
            ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
            // 读取为BufferedImage
            return ImageIO.read(bis);
        } catch (Exception e) {
            System.out.println("转换失败");
        }
        return null;

    }
}
测试方法:
    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        //大图片的base64
        String bigbase64 = null;
        //小图片的base64
        String smallbase64 = null;
        //返回得到的是X轴的距离(我的项目只需要X轴距离)   但是实际上在getDistanceByBase64ByOpenCv这个方法中,已经得到了X轴和Y轴的距离
        double XDistance = PictureUtil.getDistanceByBase64ByOpenCv(bigbase64, smallbase64);
    }
pom依赖:
        <dependency>
            <groupId>org.openpnp</groupId>
            <artifactId>opencv</artifactId>
            <version>4.5.3</version>
        </dependency>

这里的pom依赖需要根据你下载的opencv版本进行调整

这个滑块识别的方法比网上的方法好用多了,识别正确率很高,3次之内必正确

如果提示缺jar包,那就需要去这里找对应的jar包引入到项目中:

具体引入方法:

按顺序操作即可引入.

如果还有任何不懂,可在评论区或者私信问我,欢迎各位一起探讨

相关推荐
Chef_Chen几秒前
从0开始学习机器学习--Day19--学习曲线
人工智能·学习·机器学习
计算机科研狗@OUC13 分钟前
【TMM2024】Frequency-Guided Spatial Adaptation for Camouflaged Object Detection
人工智能·深度学习·目标检测·计算机视觉
悟兰因w20 分钟前
论文阅读(三十五):Boundary-guided network for camouflaged object detection
论文阅读·人工智能·目标检测
大山同学22 分钟前
多机器人图优化:2024ICARA开源
人工智能·语言模型·机器人·去中心化·slam·感知定位
Topstip29 分钟前
Gemini 对话机器人加入开源盲水印技术来检测 AI 生成的内容
人工智能·ai·机器人
Bearnaise31 分钟前
PointMamba: A Simple State Space Model for Point Cloud Analysis——点云论文阅读(10)
论文阅读·笔记·python·深度学习·机器学习·计算机视觉·3d
小嗷犬44 分钟前
【论文笔记】VCoder: Versatile Vision Encoders for Multimodal Large Language Models
论文阅读·人工智能·语言模型·大模型·多模态
Struart_R1 小时前
LVSM: A LARGE VIEW SYNTHESIS MODEL WITH MINIMAL 3D INDUCTIVE BIAS 论文解读
人工智能·3d·transformer·三维重建
lucy153027510791 小时前
【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者
人工智能·科技·单片机·嵌入式硬件·算法·机器学习
jndingxin1 小时前
OpenCV相机标定与3D重建(1)概述
数码相机·opencv·3d