猿问

提高数组列表排列的效率

作为一个小项目,我正在制作一个“密码”破解程序,它只是暴力破解字母表,数字和符号的所有排列,直到密码被猜到。


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


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


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


(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, A)(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);

            }

        }

    }

}

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


慕码人8056858
浏览 108回答 2
2回答

临摹微笑

public class BruteForce{&nbsp; &nbsp; public static String password = "CBA";&nbsp; &nbsp; public static Character[] characters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'z', '_', '-', '!', '$'};&nbsp; &nbsp; public static Integer count = 0;&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; int deep = characters.length;//password deep,default value is from one to characters.length&nbsp; &nbsp; &nbsp; &nbsp; rmark:&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 1; i <= deep; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j < characters.length; j++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(test(i,characters[j].toString())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break rmark;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public static boolean test(int deep,String parent) {&nbsp; &nbsp; &nbsp; &nbsp; if(deep <= 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(parent);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(parent.equals(password)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("after generating "+count+" strings,we find the password!");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int j = 0; j < characters.length; j++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(test(deep-1,parent+characters[j].toString())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }}

缥缈止盈

只需开始以 x 为单位计数,其中 x 是您拥有的字符数。例如,如果您只关心数字,则可以使用常规的以10为基数的系统。以这种方式看待它是微不足道的,像50045这样的东西永远不会在5之前出现。这样做非常简单,只需取一个开头为0的数组,然后每次需要新密码时,将第一个元素增加一个。如果它超过了您拥有的字符数,只需将其设置为零,然后将一个添加到下一个字符(如果是最后一个,则推送一个新元素)。你可以更简单一点,只需使用一个简单的长整型(或者BigInteger表示更大的数字,长整型对于你的设置来说不能包含超过10个字符),然后从中获取字符,只需递归地取数字的模数和你正在处理的基数,然后除以基数。这看起来像这样:for (long i = 0; i < maxNum; i++) {&nbsp; &nbsp; long temp = i;&nbsp; &nbsp; String pass = ""; // Use a StringBuilder here when actually attempting this&nbsp; &nbsp; // This would eat your memory faster than 6 chrome tabs&nbsp; &nbsp; do {&nbsp; &nbsp; &nbsp; &nbsp; pass += charset[temp % base];&nbsp; &nbsp; &nbsp; &nbsp; temp /= base;&nbsp; &nbsp; }&nbsp; while (temp > 0);}
随时随地看视频慕课网APP

相关分类

Java
我要回答