2015-01-12 1 views
1

나는 11 학년 컴퓨터 과학 프로젝트를위한 프로그램을 만들었는데, 여기서 자바 패스워드 크래커를 만들었습니다. 그러나, 나는 브루트 - 강제 프로세스를 빠르게하기 위해 자바 프로그램 (코드 제공)을 멀티 스레드하는 법에 대한 조언을 받고 싶다. 내가 인텔에서 i7-3770 프로세서를 돌리고 있으며 쿼드 코어이지만 코어 당 스레드가 2 개이므로 8 개의 가능한 스레드를 동시에 사용할 수 있습니다.무차직 자바 패스워드 프로그램을 멀티 스레드하는 법

import java.util.*; 
import java.io.*; 
class pwcracker 
{ 
public static void main (String[] args) 
{ 
Scanner scan = new Scanner(System.in); 
Random rand = new Random(); 

Runtime.getRuntime().availableProcessors(); 

String pw, choices, guess; 
long tries; 
int j, length; 

System.out.println("Enter a password that is up to 5 chars and contains no numbers: "); 
pw = "" + scan.nextLine(); 
length = pw.length(); 

choices = "abcdefghijklmnopqrstuvwxyz"; 
tries = 0; 
guess = ""; 

System.out.println("Your pw is: " + pw); 
System.out.println("The length of your pw is: " + length); 

System.out.println("for TEST- Guess: " + guess + "pw :"+pw); 


if (guess != pw){ 

while (guess != pw) 
{ 
    j = 0; 
    guess = ""; 

    while (j < length) 
    { 
     guess = guess + choices.charAt(rand.nextInt (choices.length())); 
     j = j + 1; 

    if (guess == pw) 
{ 
    System.out.println("Match found, ending loop.."); 
    break; 
} 

    } 
      System.out.println("2 Guess: " + guess + " pw :"+pw); 

    tries = tries + 1;      
} 
} 
System.out.println("Here is your password: " + guess); 
System.out.println("It took " + tries + " tries to guess it."); 
} 
} 
+1

자바에서는 문자열을 비교할 때 ==를 사용할 수 없습니다. string1.equals (string2)를 사용해야합니다. – slipperyseal

+1

프로그램이 하이퍼 스레딩되지 않았으며 프로세서가 하이퍼 스레딩되었습니다. 그리고 프로세서 스레드는 코어보다 소프트웨어 쓰레드와 더 이상 관련이 없습니다. – immibis

+0

예, 죄송합니다. 내 말에 .equals 대신 ==를 사용하도록 코드를 업데이트 한 것을 잊어 버렸습니다. 더 이상 버그가 없으므로 –

답변

0

이것은 병렬 처리 솔루션이 아니라 훨씬 더 최적화 된 무차별 대입 방식입니다. Iterator를 Spliterator로 변경하는 것을 고려할 수 있습니다. 시간이 허락한다면 나는 다음 포스트에서 Spliterator 접근법을 제공 할 것입니다.

package pwcracker; 

import java.util.Iterator; 
import java.util.Scanner; 

public class pwcracker { 

    public static void main(String[] args) { 
     Scanner scan = new Scanner(System.in); 
     String pw; 
     int length; 

     System.out.println("Enter a password that is up to 5 chars and contains no numbers: "); 
     pw = "" + scan.nextLine(); 
     length = pw.length(); 

     SequentialPatternGenerator generator = new SequentialPatternGenerator(length); 

     generator.forEachRemaining(test -> {if(pw.equals(test)) { 
      System.out.println("Your password: " + test); 
     }}); 

    } 
} 

class SequentialPatternGenerator implements Iterator<String> { 

    private static final char[] CHOICES = new char[]{'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'}; 

    private static final int MAX_INDEX = CHOICES.length - 1; 
    private boolean keepProducing = true; 
    private final int[] indexes; 

    public SequentialPatternGenerator(final int length) { 
     indexes = new int[length]; 
     initIndexes(); 
    } 

    private void initIndexes() { 
     for (int i = 0; i < indexes.length; i++) { 
      indexes[i] = 0; 
     } 
    } 

    @Override 
    public boolean hasNext() { 
     if (!keepProducing) { 
      return false; 
     } 

     for (int i = 0; i < indexes.length; i++) { 
      if (indexes[i] < MAX_INDEX) { 
       return true; 
      } 
     } 

     return false; 
    } 

    @Override 
    public String next() { 
     if (!keepProducing || !hasNext()) { 
      return null; 
     } 

     String next = produceString(); 
     adjustIndexes(); 

     return next; 
    } 

    public void stop() { 
     keepProducing = false; 
    } 

    private String produceString() { 
     StringBuilder sb = new StringBuilder(); 
     for (int i = 0; i < indexes.length; i++) { 
      sb.append(CHOICES[indexes[i]]); 
     } 

     return sb.toString(); 
    } 

    private void adjustIndexes() { 
     int i; 
     for(i = 0 ; i < indexes.length ; i++) { 
      if(indexes[i] < MAX_INDEX) { 
       indexes[i] = indexes[i] + 1; 
       break; 
      } 
     } 

     for(int j=0; j < i; j++) { 
      indexes[j] = 0; 
     } 
    } 
} 
+0

와우! 고마워, 훨씬 빠르다! –

0

먼저 당신이 많은 unnecssary 기능이 가능한 루프에서 호출을 줄이고 자 : 여기

는 코드입니다. 예를 들어 choices.length는 메모리에 변수로 저장 될 수 있습니다. int choice = choice.length. 이렇게하면 컴퓨터가 길이를 계산할 필요가 없을 때마다 메모리에 이미 저장되어 있으므로 사용할 때마다 프로그램이 최적화됩니다.

+0

이것은 답변이 아닙니다. – VGR

0

스레드 경로로 가고 싶다면 producer-consumer 알고리즘으로 설정하면됩니다. 높은 레버에서 우리는 생산자 쓰레드로 작업을 생성하고, 우리는 소비자 쓰레드를 사용하여 작업 단위를 생산자에서 소비자로 전송하는 공유 큐 객체를 갖게됩니다.

귀하의 경우 샘플 공간이 상대적으로 작기 때문에 (길이가 5 인 순열), 단일 제작자 스레드가 있습니다. 아래의 제안을 사용하면 간단하게 유지할 수 있습니다. This tutorial는 당신을위한 출발점으로 아주 단순 해 보입니다. 사용하려는 총 스레드 수만큼 작게 시작하고 다른 수의 스레드로 재생하십시오.

나는 무작위로 확인할 문자열을 만들고있는 것을 알았습니다. 그러나 반복적 인 중복 검사를 많이 만들 수 있으므로 순열을 사용하는 것이 좋습니다. 즉, 길이 5의 알파벳 문자의 모든 순열이 필요합니다.이 라이브러리는 combinations and permutations입니다. 이렇게하면 반복하지 않고 모든 가능한 조치를 취할 수 있습니다. 이런 식으로 뭔가 :

// Create the initial vector of 26 elements (alphabet) 
ICombinatoricsVector<char> originalVector = Factory.createVector(new char[] { 'a', 'b', 'c', ..., 'z' }); 

// Create the generator by calling the appropriate method in the Factory class. 
// Set the second parameter as 5, since we will generate 5-elemets permutations 
Generator<char> gen = Factory.createPermutationWithRepetitionGenerator(originalVector, 5); 

// Print the result 
for (ICombinatoricsVector<char> perm : gen) 
    System.out.println(perm); //combine the elements of perm into a single string and add to your queue 

(경고 : 나는 위의 테스트하지 않았다) : 나는 이것에 대해 생각하면서 조합과 순열의 차이를 볼 수밖에 없었습니다 :) 내가이 링크를 유용하다고 편집

http://www.mathsisfun.com/combinatorics/combinations-permutations.html

관련 문제