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

news2025/4/5 13:27:35

使用技术: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包引入到项目中:

具体引入方法:

按顺序操作即可引入.

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1631988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CANoe示例分析】TCP Chat(CAPL) with TLS encription

1、工程路径 C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 15.3.89\Ethernet\Simulation\TLSSimChat 在CANoe软件上也可以打开此工程:File|Help|Sample Configurations|Ethernet - Simulation of Ethernet ECUs|Basic AUTOSAR Adaptive(SOA) 2、示例目…

嘉楠堪智 CanMV K230 的 CanMV-IDE 环境与 MicroPython 编程

嘉楠推出了 CanMV IDE 开发环境&#xff0c;可以使用 MicroPython 开发针对 CanMV K230 的各种程序&#xff0c;同时也提供了大量的例子程序&#xff0c;方便使用者学习。 嘉楠开发者社区&#xff0c;给出了详细的 CanMV K230 教程&#xff0c;可以借以快速上手。 目录 固件…

【Java难点】多线程终极

悲观锁和乐观锁 悲观锁 synchronized关键字和Lock的实现类都是悲观锁。 它很悲观&#xff0c;认为自己在使用数据的时候一定有别的线程来修改数据&#xff0c;因此在获取数据的时候会一不做二不休的先加锁&#xff0c;确保数据不会被别的线程修改。 适合写操作多的场景&…

船用组装式中央空调案例

船用组装式空调的整体介绍 1.1 装置的主要技术数据及配套设备规格 该轮采用的是船用组装式空调装置。 1.1.1 空调装置 1&#xff09;型号&#xff1a;CJKR-116船用组装式空调装置&#xff1b;2&#xff09;制冷型式&#xff1a;直接蒸发式&#xff1b;3&#xff09;制冷量&…

【汇编】#6 80x86指令系统其二(串处理与控制转移与子函数)

文章目录 一、串处理指令1. 与 REP 协作的 MOVS / STOS / LODS的指令1.1 重复前缀指令REP1.2 字符串传送指令&#xff08;Move String Instruction&#xff09;1.2 存串指令&#xff08;Store String Instruction&#xff09;1.3 取字符串指令&#xff08;Load String Instruct…

VULHUB复现fastjson1.2.24反序列化漏洞

蚌埠住了&#xff0c;遇到了很多奇奇怪怪的问题。 如果你问我为啥不用kali&#xff0c;我会告诉你&#xff0c;我电脑上的kali装不成docker-compose!我急用了ubuntu如果你问我为啥用ubuntu克隆&#xff0c;我会告诉你&#xff0c;我电脑上的kali不能安装成功java8这个版本如果你…

一二三应用开发平台使用手册——系统管理-权限项模块-使用说明

权限项 概述 在RBAC模型中&#xff0c;资源、角色、用户三个关键元素&#xff0c;构成权限体系。资源是权限控制的对象&#xff0c;因此常称之为权限项。 平台中所有的权限项进行集中管理&#xff0c;菜单、按钮、请求、分组等通过类型进行区分&#xff0c;实体与库表公用&a…

读天才与算法:人脑与AI的数学思维笔记13_Coq证明助手

1. 计算机 1.1. 对于计算机来说&#xff0c;它就很擅长处理这种重复而机械且计算量庞大的任务 1.1.1. 在速度与准确性等方面&#xff0c;计算机是远超过手工计算的 1.2. 计算机只能执行指令&#xff0c;并无自主创造力 1.2.1. 想…

第七天 dfs剪枝优化

第七天 dfs剪枝&优化 1可行性剪枝 2最优性剪枝 3重复性剪枝 题 1 输入 5 5 6 …S. XX.X. …X… …D.X …X… 输出 YES —————————————— 题解 #include<iostream> #include<cstdio> using namespace std; const int N 10; int n,m,T; char …

分治策略 --- 快排归并

目录 分治-快排 一、颜色分类 二、排序数组 三、数组中的第K个最大元素 四、库存管理 分治-归并 一、排序数组 二、交易逆序对的总数 三、计算右侧小于当前元素的个数 四、翻转对 分治是一种思想&#xff0c;也就是将大问题分解成小问题&#xff0c;一直分到小问题可…

【bug已解决】发生错误,导致虚拟 CPU 进入关闭状态。如果虚拟机外部发生此错误,则可能已导致物理计算机重新启动......

本bug报错已找到原因,并成功解决。 项目场景: vmware安装ubuntu报错。 如下: 发生错误,导致虚拟 CPU 进入关闭状态。如果虚拟机外部发生此错误,则可能已导致物理计算机重新启动。错误配置虚拟机、客户机操作系统中的错误或 VMware Workstation 中的问题都可以导致关闭状…

关于google search console工具提交sitemap.xml无法抓取的问题解决办法

其实这个问题很好解决。 第一种情况&#xff1a;利用工具为我们的网站自动生成静态的sitemap.xml文件。这种可以检查下是否完整&#xff0c;然后上传到根目录下去&#xff0c;再去google search console提交我们的网站地图。 第二种情况&#xff1a;同样利用工具自动生成动态s…

idea中使用GlassFish服务器启动项目

idea中使用GlassFish服务器进行测试 1.项目背景 当前在研究openMDM项目, 不过该项目不是springboot项目, 并且是使用GlassFish进行war部署的, 但是需要在idea中进行项目的二次开发,故需要进行idea启动项目并且进行开发和调试 2.GlassFish是什么 GlassFish是一个web服务器, …

用来传输文件的协议-FTP

一.FTP协议--文件传输协议 1.了解FTP协议 &#xff08;1&#xff09;FTP服务是用来传输文件的协议 FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;是TCP/IP协议组中的协议之一&#xff0c;用于互联网上的控制文件的双向传输。是传输文件到Linu…

图像置乱加密-Arnold加密算法

置乱加密是另一种较常用的加密方法&#xff0c;现也被许多文献选用&#xff0c;置乱加密可以是以像素为单位进行全局置乱&#xff0c;该方式打乱了图像像素值的位置&#xff0c;使其图像内容失去相关性&#xff0c;达到保护的目的。也可以是以块为单位进行置乱&#xff0c;该方…

软件开发技巧---TODO特殊事项标注

软件开发技巧—TODO特殊事项标注 文章目录 软件开发技巧---TODO特殊事项标注1、前言2、环境3、TODO注释规范4、Qt中使用TODO5、VS中使用TODO6、总结 更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;开发工具 &#x1f448; 1、前言 &#x1f9d8;&…

头歌:Spark的安装与使用

第1关&#xff1a;Scala语言开发环境的部署 相关知识 Scala是一种函数式面向对象语言&#xff0c;它融汇了许多前所未有的特性&#xff0c;而同时又运行于JVM之上。随着开发者对Scala的兴趣日增&#xff0c;以及越来越多的工具支持&#xff0c;无疑Scala语言将成为你手上一件…

电脑已经有了一个Windows10,再多装一个Windows10组成双系统

前言 前段时间已经讲过一次双Windows系统的安装教程&#xff0c;但是小白重新去看了一下&#xff0c;发现写的内容太多&#xff0c;怕小伙伴看了之后一脸萌。 所以今天咱们就重新再来讲讲&#xff1a;在同一台机器上安装Windows10双系统的教程。 注意哦&#xff01;这里的Wi…

paddlehub的简单应用

1、下载安装 pip install paddlehub -i https://pypi.tuna.tsinghua.edu.cn/simple 报错&#xff1a; Collecting onnx<1.9.0 (from paddle2onnx>0.5.1->paddlehub)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/73/e9/5b953497c0e36df589fc60cc6c6b35…

语音识别的基本概念

语音识别的基本概念​​​​​​​ ​​​​​​​ 言语是一种复杂的现象。人们很少了解它是如何产生和感知的。天真的想法常常是语音是由单词构成的&#xff0c;而每个单词又由音素组成。不幸的是&#xff0c;现实却大不相同。语音是一个动态过程&#xff0c;没有明确区分的…