2015-01-12 69 views
1

我創建了一個程序,爲我的11年級計算機科學項目,我做了一個java密碼破解蠻力的密碼。不過,我想獲得一些關於如何對我的java程序(下面提供的代碼)進行多線程加速的建議,以加速蠻力程序。如果它有幫助,我可以使用英特爾的i7-3770處理器,它是四核處理器,但每個內核有2個線程,因此可以同時處理8個可能的線程。如何多線程的蠻力java密碼程序

下面是代碼:

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

你不能使用==比較java中的字符串。你需要使用string1.equals(string2) – slipperyseal

+1

程序不是超線程的,處理器是超線程的。處理器線程與軟件線程沒有任何關係。 – immibis

+0

是的抱歉,我忘了提及我更新了代碼在我的最後使用.equals而不是==所以這不是一個錯誤 –

回答

0

這不是一個並行處理解決方案,而是一個更加優化的暴力方法。您可以考慮將迭代器更改爲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