【代码】zip压缩文件密码暴力破解

代码

ini 复制代码
import java.io.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.io.FileUtils;

/**
 * 密码生成器接口 - 策略模式
 */
interface PasswordGenerator {
    String nextPassword(Integer lastExecutePosition);

    long getCurrentCount();

    long getTotalCombinations();
}

/**
 * 破解状态接口 - 状态模式
 */
interface CrackState {
    void crack(ZipFile password, ZipCracker.ProgressMonitor progressMonitor);

    void onSuccess(String password);

    void onFailure();
}

/**
 * 破解命令接口 - 命令模式
 */
interface CrackCommand {
    void execute();

    void undo();
}

/**
 * 观察者接口 - 观察者模式
 */
interface CrackObserver {
    void onProgressUpdate(long current, long total);

    void onPasswordFound(String password);

    void onCrackComplete();
}

/**
 * 破解器构建器 - 建造者模式
 * <p>
 * 用于创建复杂对象
 * 提供流式接口设置参数
 * 将对象创建与参数设置分离
 */
class ZipCrackerBuilder {
    // 修改为protected,允许ZipCracker访问
    protected int threadCount = Runtime.getRuntime().availableProcessors() * 2;
    protected String zipFilePath;
    protected int minLength;
    protected int maxLength;
    protected String outputDir;
    protected CrackObserver observer;

    protected PasswordGenerator passwordGenerator;
    protected ZipCracker.ProgressMonitor progressMonitor;

    public ZipCrackerBuilder setThreadCount(int count) {
        this.threadCount = count;
        return this;
    }

    public ZipCrackerBuilder setZipFilePath(String path) {
        this.zipFilePath = path;
        return this;
    }

    public ZipCrackerBuilder setPasswordLength(int min, int max) {
        this.minLength = min;
        this.maxLength = max;
        return this;
    }

    public ZipCrackerBuilder setOutputDir(String dir) {
        this.outputDir = dir;
        return this;
    }

    public ZipCrackerBuilder setObserver(CrackObserver observer) {
        this.observer = observer;
        return this;
    }
    public ZipCrackerBuilder setPasswordGenerator(PasswordGenerator passwordGenerator) {
        this.passwordGenerator = passwordGenerator;
        return this;
    }

    public ZipCrackerBuilder setProgressMonitor(ZipCracker.ProgressMonitor progressMonitor) {
        this.progressMonitor = progressMonitor;
        return this;
    }
    public ZipCracker build() {
        return new ZipCracker(this);
    }
}

/**
 * ClassName: ZipCracker
 * Description: ZIP密码破解工具,支持多线程和进度显示
 * 使用多种设计模式优化代码结构
 *
 * @author wanjinjun
 * @version 1.0
 * @Copyright: Copyright (c) wanjinjun
 * @Date 2025/3/30 22:42
 */
public class ZipCracker {
    // 单例模式:管理全局状态
    private static final AtomicBoolean passwordFound = new AtomicBoolean(false);
    private static String FOUND_PASSWORD = new String();

    // 建造者模式:配置参数
    private final int threadCount;
    private final String zipFilePath;
    private final int minLength;
    private final int maxLength;
    private final String outputDir;
    private final CrackObserver observer;
    private final PasswordGenerator passwordGenerator;
    private final ProgressMonitor progressMonitor;
    private final ZipFile zipFile;

    // 状态模式:当前破解状态
    private CrackState currentState;

    // 修改为protected,允许ZipCrackerBuilder访问
    protected ZipCracker(ZipCrackerBuilder builder) {
        this.threadCount = builder.threadCount;
        this.zipFilePath = builder.zipFilePath;
        this.minLength = builder.minLength;
        this.maxLength = builder.maxLength;
        this.outputDir = builder.outputDir;
        this.zipFile = new ZipFile(zipFilePath);
        this.observer = builder.observer;
        this.passwordGenerator = new BruteForcePasswordGenerator(minLength, maxLength);
        this.progressMonitor = new ProgressMonitor(passwordGenerator);
        this.currentState = new InitialState(this);

    }

    /**
     * 执行密码破解
     * 模板方法模式:定义破解流程骨架
     */
    public String crack() {
        try {
            // 1. 初始化
            initialize();

            // 2. 创建线程池
            ExecutorService executor = Executors.newFixedThreadPool(threadCount);

            // 3. 提交破解任务
            submitCrackTasks(executor);

            // 4. 等待完成
            waitForCompletion(executor);

            // 5. 返回结果
            return getResult();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private void initialize() {
        // 初始化工作
        new File(outputDir).mkdirs();
    }

    private void submitCrackTasks(ExecutorService executor) {
        // 提交破解任务
        for (int i = 0; i < threadCount; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    // 创建破解命令
                    CrackCommand command = new CrackCommand() {
                        @Override
                        public void execute() {
                            currentState.crack(zipFile, progressMonitor);
                        }

                        @Override
                        public void undo() {
                            // 清理临时文件等
                        }
                    };

                    // 执行命令
                    command.execute();
                }
            });
        }
    }

    private void waitForCompletion(ExecutorService executor) throws InterruptedException {
        executor.shutdown();
        executor.awaitTermination(12, TimeUnit.HOURS);
    }

    private String getResult() {
        return passwordFound.get() ? FOUND_PASSWORD : null;
    }

    // 状态类实现
    private class InitialState implements CrackState {
        private final ZipCracker cracker;

        public InitialState(ZipCracker cracker) {
            this.cracker = cracker;
        }

        @Override
        public void crack(ZipFile zipFile, ZipCracker.ProgressMonitor progressMonitor) {
            // 实现破解逻辑
            while (!passwordFound.get()) {
                observer.onProgressUpdate(progressMonitor.generator.getCurrentCount(),
                        progressMonitor.generator.getTotalCombinations());
                String password = progressMonitor.generator.nextPassword(null);
                System.out.println("此次密码 : " + password);
                if (password == null) {
                    break;
                }
                try {
                    zipFile.setPassword(password.toCharArray());
                    zipFile.setCharset(java.nio.charset.Charset.forName("GBK"));
                    // 获取第一个文件
                    FileHeader firstFile = zipFile.getFileHeaders().get(0);
                    // 尝试解压第一个文件到临时目录
                    String tempDir = outputDir + "temp_" + Thread.currentThread().getId();
                    new File(tempDir).mkdirs();
                    zipFile.extractFile(firstFile, tempDir);
                    // 如果成功解压,说明密码正确
                    onSuccess(password);
                    // 清理临时文件
                    FileUtils.deleteDirectory(new File(tempDir));
                    break;
                } catch (Exception e) {
                    // net.lingala.zip4j.exception.ZipException: Wrong password! 密码错误,继续尝试
                    continue;
                }
            }

        }

        @Override
        public void onSuccess(String password) {
            passwordFound.set(true);
            FOUND_PASSWORD = password;
            if (observer != null) {
                observer.onPasswordFound(password);
            }
            System.out.println("正确 此次密码 : " + password);
        }

        @Override
        public void onFailure() {
            // 处理失败情况
        }
    }

    // 进度监控器实现
    public static class ProgressMonitor implements CrackObserver {
        private final PasswordGenerator generator;
        private volatile boolean running = true;

        public ProgressMonitor(PasswordGenerator generator) {
            this.generator = generator;
        }

        public void stop() {
            running = false;
        }

        @Override
        public void onProgressUpdate(long current, long total) {
            double progress = (double) current / total * 100;
            System.out.printf("破解进度: %.2f%% (已尝试: %d/%d)\n", progress, current, total);
        }

        @Override
        public void onPasswordFound(String password) {
            System.out.println("密码已找到: " + password);
        }

        @Override
        public void onCrackComplete() {
            System.out.println("破解完成");
            stop();
        }
    }

    // 密码生成器实现
    private static class BruteForcePasswordGenerator implements PasswordGenerator {
        private final int minLength;
        private final int maxLength;
         private final char[] chars ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.@~!#$".toCharArray();


        private long currentCount = 0;
        private final long totalCombinations;

        public BruteForcePasswordGenerator(int minLength, int maxLength) {
            this.minLength = minLength;
            this.maxLength = maxLength;
            this.totalCombinations = calculateTotalCombinations();
        }

        private long calculateTotalCombinations() {
            long total = 0;
            for (int len = minLength; len <= maxLength; len++) {
                total += (long) Math.pow(chars.length, len);
            }
            return total;
        }

        @Override
        public synchronized String nextPassword(Integer lastExecutePosition) {
            if (lastExecutePosition != null) {
                currentCount = lastExecutePosition;
            }
            if (currentCount >= totalCombinations) {
                return null;
            }
            return generatePassword(currentCount++);
        }

        private String generatePassword1(long currentCount) {
            StringBuilder password = new StringBuilder();
            int length = minLength;
            long remaining = currentCount;

            for (int len = minLength; len <= maxLength; len++) {
                long combinations = (long) Math.pow(chars.length, len);
                if (remaining < combinations) {
                    length = len;
                    break;
                }
                remaining -= combinations;
            }

            for (int i = 0; i < length; i++) {
                password.append(chars[(int) (remaining % chars.length)]);
                remaining /= chars.length;
            }
            return password.toString();
        }

        private String generatePassword(long currentCount) {
            StringBuilder password = new StringBuilder();
            int length = minLength;
            long remaining = currentCount;

            // 确定密码长度
            for (int len = minLength; len <= maxLength; len++) {
                long combinations = calculateCombinations(len);
                if (remaining < combinations) {
                    length = len;
                    break;
                }
                remaining -= combinations;
            }

            // 生成密码字符
            for (int i = 0; i < length; i++) {
                password.append(chars[(int) (remaining % chars.length)]);
                remaining /= chars.length;
            }

            // 反转字符串以修正顺序
            return password.reverse().toString();
        }

        /**
         *  long combinations = (long) Math.pow(chars.length, len);
         * @param len
         * @return
         */
        private long calculateCombinations(int len) {
            long combinations = 1;
            for (int i = 0; i < len; i++) {
                if (combinations > Long.MAX_VALUE / chars.length) {
                    return Long.MAX_VALUE;
                }
                combinations *= chars.length;
            }
            return combinations;
        }


        @Override
        public long getCurrentCount() {
            return currentCount;
        }

        @Override
        public long getTotalCombinations() {
            return totalCombinations;
        }
    }

    // 主方法示例
    public static void main(String[] args) {

        String zipFilePath = "E:\\Project\\tmp.zip";
        String outputFilePath = "E:\\Project\\output";


        System.out.println("----------------测试单密码破解--------- Begin-------------");
        
        String password = "123456";
        ZipFile zipFile = new ZipFile(zipFilePath);
        try {
            zipFile.setPassword(password.toCharArray());
            zipFile.setCharset(java.nio.charset.Charset.forName("GBK"));
            zipFile.extractAll(outputFilePath);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        System.out.println("---------------测试单密码破解-----------End----------");


        PasswordGenerator  passwordGenerator= new BruteForcePasswordGenerator(6, 6);
        ProgressMonitor progressMonitor  = new ProgressMonitor(passwordGenerator);
        // 使用建造者模式创建破解器
        ZipCracker cracker = new ZipCrackerBuilder()
                .setZipFilePath(zipFilePath)
                .setPasswordLength(4, 12)
                .setOutputDir(outputFilePath)
                .setPasswordGenerator(passwordGenerator)
                .setProgressMonitor(progressMonitor)
                .setObserver( progressMonitor)
                .build();

        // 执行破解
        String result = cracker.crack();
        if (result != null) {
            System.out.println("密码破解成功!密码是: " + result);
        } else {
            System.out.println("未能找到正确的密码。");
        }
    }
}

zip4j

xml 复制代码
 
<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.10.0</version> <!-- 请使用最新的版本号 -->
</dependency>
 
相关推荐
嘉友25 分钟前
Redis zset数据结构以及时间复杂度总结(源码)
数据结构·数据库·redis·后端
苏三说技术1 小时前
Excel百万数据如何快速导入?
后端
昵称为空C1 小时前
SpringBoot编码技巧-ScheduledExecutorService轮询
java·spring boot·后端
huangyingying20252 小时前
03-分支结构
后端
00后程序员2 小时前
【Flutter -- 基础组件】Flutter 导航栏
后端
bobz9652 小时前
ovs internal port 对比 veth-pair 性能
后端
Auroral1562 小时前
基于RabbitMQ的异步通知系统设计与实现
前端·后端
易元2 小时前
设计模式-代理模式
java·后端
嘻嘻哈哈开森2 小时前
Java开发工程师转AI工程师
人工智能·后端
LTPP2 小时前
自动化 Rust 开发的革命性工具:lombok-macros
前端·后端·github