Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 提高ArrayList置换的效率_Java_Arraylist_Permutation - Fatal编程技术网

Java 提高ArrayList置换的效率

Java 提高ArrayList置换的效率,java,arraylist,permutation,Java,Arraylist,Permutation,作为一个小项目,我正在制作一个“密码”破解器,它可以通过所有字母表、数字和符号的排列,直到猜到密码为止 当然,这是非常低效的,我正在寻找方法使它更快一点 我的想法是让排列按大小顺序进行。所以现在,它将从ArrayList中的第一个字符开始,并不断添加下一个字符,猜测将变得越来越大。比如说 一个具有值(A,B,C,D)的数组列表,我当前的程序将创建如下排列: for (long i = 0; i < maxNum; i++) { long temp = i; String p

作为一个小项目,我正在制作一个“密码”破解器,它可以通过所有字母表、数字和符号的排列,直到猜到密码为止

当然,这是非常低效的,我正在寻找方法使它更快一点

我的想法是让排列按大小顺序进行。所以现在,它将从
ArrayList
中的第一个字符开始,并不断添加下一个字符,猜测将变得越来越大。比如说

一个具有值
(A,B,C,D)
数组列表
,我当前的程序将创建如下排列:

for (long i = 0; i < maxNum; i++) {
    long temp = i;
    String pass = ""; // Use a StringBuilder here when actually attempting this
    // This would eat your memory faster than 6 chrome tabs
    do {
        pass += charset[temp % base];
        temp /= base;
    }  while (temp > 0);
}
(A)
(A,B)
(A,B,C)
(A,B,C,D)
(A,B,D)
(A,B,D,C)

但是一种更有效的方法(因为大多数密码长度不超过60个字符),是通过这样的排列

(A)
(B)
(C)
(D)
(A,B)
(A,C)
(A,D)
(B,C)
等等

这就是我当前的计划:

import java.util.ArrayList;
import java.util.Arrays;

public class BruteForce
{

    public static String password = "rand1";

    public static void main(String[] args) {
        ArrayList<Character> characters = new ArrayList<>(Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
                'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3',
                '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
                'z', '_', '-', '!', '$'));

        initialPermutations(characters);
    }

    public static void initialPermutations(ArrayList<Character> characters) {
        ArrayList<Character> sub = new ArrayList<>();
        finalPermutations(sub, characters);
    }

    public static void finalPermutations(ArrayList<Character> sub, ArrayList<Character> a) {
        int L = a.size();
        char[] cs = new char[sub.size()];
        for(int i = 0; i < cs.length; i++) {
            cs[i] = sub.get(i);
        }

        String output = new String(cs);

        if(output.equals(password)) {
            System.out.println("The password is " + output);
            System.exit(-1);
        }

        if (L == 0) {
            System.out.println(output);
        }else {

            System.out.println(output);
            for (int i = 0; i < L; i++) {
                ArrayList<Character> ab = new ArrayList<>(sub);
                ab.add(a.get(i));
                ArrayList<Character> bc = new ArrayList<>(a);
                bc.remove(i);
                finalPermutations(ab, bc);
            }
        }
    }
}
import java.util.ArrayList;
导入java.util.array;
公共类暴力
{
公共静态字符串password=“rand1”;
公共静态void main(字符串[]args){
ArrayList characters=新的ArrayList(数组.asList('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',),
‘P’、‘Q’、‘R’、‘S’、‘T’、‘U’、‘V’、‘W’、‘X’、‘Y’、‘Z’、‘0’、‘1’、‘2’、‘3’,
‘4’、‘5’、‘6’、‘7’、‘8’、‘9’、‘a’、‘b’、‘c’、‘d’、‘e’、‘f’、‘g’、‘h’、‘i’,
‘j’、‘k’、‘l’、‘m’、‘n’、‘o’、‘p’、‘q’、‘r’、‘s’、‘t’、‘u’、‘v’、‘w’、‘x’、‘y’,
"z","u","-","!","美元";;
初始排列(字符);
}
公共静态无效初始置换(ArrayList字符){
ArrayList sub=新的ArrayList();
最终术语(子术语、字符);
}
公共静态无效最终条款(ArrayList子,ArrayList a){
int L=a.size();
char[]cs=新字符[sub.size()];
对于(int i=0;i

关于如何将其改进为更“高效”(实际上不是更高效,只是对于较短的密码更有用)的方法,有什么想法吗?

只需开始以x为基数计算,其中x是您拥有的字符数。例如,如果你只关心数字,你会使用常规的10进制。从这个角度来看,50045这样的东西在5点之前是不会出现的,这是很平常的

这样做非常简单,只需在开始时获取一个包含0的数组,然后每次需要新密码时,将第一个元素增加1。如果它超过了您拥有的字符数,只需将其设置为零并向下一个字符添加一个字符(如果是最后一个字符,则推送一个新元素)

只需使用一个简单的long(或BigInteger,用于较大的数字,long不能包含超过10个字符,用于设置),就可以实现比这简单一点的操作,然后从中获取字符,只需递归地获取数字和正在处理的基的模,然后除以基。这看起来像这样:

for (long i = 0; i < maxNum; i++) {
    long temp = i;
    String pass = ""; // Use a StringBuilder here when actually attempting this
    // This would eat your memory faster than 6 chrome tabs
    do {
        pass += charset[temp % base];
        temp /= base;
    }  while (temp > 0);
}
for(长i=0;i0);
}

只需开始以x为基数计算,其中x是您拥有的字符数。例如,如果你只关心数字,你会使用常规的10进制。从这个角度来看,50045这样的东西在5点之前是不会出现的,这是很平常的

这样做非常简单,只需在开始时获取一个包含0的数组,然后每次需要新密码时,将第一个元素增加1。如果它超过了您拥有的字符数,只需将其设置为零并向下一个字符添加一个字符(如果是最后一个字符,则推送一个新元素)

只需使用一个简单的long(或BigInteger,用于较大的数字,long不能包含超过10个字符,用于设置),就可以实现比这简单一点的操作,然后从中获取字符,只需递归地获取数字和正在处理的基的模,然后除以基。这看起来像这样:

for (long i = 0; i < maxNum; i++) {
    long temp = i;
    String pass = ""; // Use a StringBuilder here when actually attempting this
    // This would eat your memory faster than 6 chrome tabs
    do {
        pass += charset[temp % base];
        temp /= base;
    }  while (temp > 0);
}
for(长i=0;i0);
}
公共类暴力{
公共静态字符串password=“CBA”;
公共静态字符[]字符={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
‘P’、‘Q’、‘R’、‘S’、‘T’、‘U’、‘V’、‘W’、‘X’、‘Y’、‘Z’、‘0’、‘1’、‘2’、‘3’,
‘4’、‘5’、‘6’、‘7’、‘8’、‘9’、‘a’、‘b’、‘c’、‘d’、‘e’、‘f’、‘g’、‘h’、‘i’,
‘j’、‘k’、‘l’、‘m’、‘n’、‘o’、‘p’、‘q’、‘r’、‘s’、‘t’、‘u’、‘v’、‘w’、‘x’、‘y’,
‘z’、‘_’、‘-’、‘!’、’$