2013-10-29 3 views
0

나는 학교 균열로 패스트 워드 크래킹 프로그램 (웹 마스터 사전 비교 및 ​​일치 찾기)을하고 있습니다. 스레드와 바운드 된 버퍼를 사용하는 파이프 라인 아키텍처입니다. 첫 번째 질문은 다음과 같습니다하나 이상의 스레드를 추가 한 후에 빌드가 성공하지 못했습니다. 패스워드 크래킹 파이프 라인

  1. 이 여전히 있기 때문에 variations- 만드는 것이 빠른 처리, 하나의 파일 때문에 읽는 것이 더 많은 스레드를 사용하는 경우에도 중앙 (암호) 크래커 (하나보다 느린 이유 3x 암호화 스레드보다 빠름, 암호화를위한 3 개의 스레드 - 매우 느린 프로세스 및 finnaly 비교를위한 하나의 스레드이기 때문에)?

  2. 왜 암호화를 위해 4 번째 스레드를 추가 할 때 스레드가 완료 될 때 프로그램의 끝에 성공적으로 작성된 빌드가 없습니다.

예를 들어 뭔가가 필요한 경우 언제든지 답변 해 주셔서 감사합니다. 내 실험이 묻는다.

CODE : 암호화 클래스

package passwordcracking; 

import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Encrypt implements Runnable { 

private static final Logger LOGGER = Logger.getLogger("passwordCracker"); 
private final Buffers<String> bufferTakeFrom; 
private final Buffers<PairEncPWandClearPW> bufferPutTo; 
String possiblePassword; 
private MessageDigest messageDigest; 

/** 
* 
* @param bufferTakeFrom 
*/ 
public Encrypt(Buffers<String> bufferTakeFrom, Buffers<PairEncPWandClearPW>   

bufferPutTo) 
{ 
    this.bufferTakeFrom = bufferTakeFrom; 
    this.bufferPutTo = bufferPutTo; 
    try { 
     messageDigest = MessageDigest.getInstance("SHA"); 
    } catch (NoSuchAlgorithmException ex) { 
     LOGGER.log(Level.SEVERE, ex.getMessage()); 
     throw new RuntimeException(ex); 
    } 
} 

@Override 
public void run() { 
    do { 
     possiblePassword = bufferTakeFrom.take(); 
     EncryptSingleWord(possiblePassword); 
    } while (!possiblePassword.equals("-1")); 

} 

private void EncryptSingleWord(final String possiblePassword) { 
    byte[] digest = null; 
    try { 
     digest = messageDigest.digest(possiblePassword.getBytes()); 
     PairEncPWandClearPW pair = new PairEncPWandClearPW(digest, possiblePassword); 
     bufferPutTo.put(pair); 
    } catch (Exception ex) { 
     System.out.println("Exception: " + ex); 
     System.out.println("possible password bytes: " + possiblePassword.getBytes()); 
     System.out.println("password:" + possiblePassword); 

    } 

}} 

만들기 변동 클래스 :

package passwordcracking; 

import utilities.StringUtilities; 

/** 
* 
* @author zatokar 
*/ 
public class MakeVariations implements Runnable { 

Buffers<String> bufferTakeFrom; 
Buffers<String> bufferPutTo; 
String dictionaryEntry; 

public MakeVariations(Buffers<String> bufferTakeFrom, Buffers<String> bufferPutTo) { 
    this.bufferTakeFrom = bufferTakeFrom; 
    this.bufferPutTo = bufferPutTo; 
} 

@Override 
public void run() { 
    do { 
     dictionaryEntry = bufferTakeFrom.take(); 
     makeVariations(dictionaryEntry); 
     if (dictionaryEntry.equals("-1")) { 
      System.out.println("Make variations thread finished."); 
     } 
    } while (!dictionaryEntry.equals("-1")); 
} 

public void makeVariations(final String dictionaryEntry) { 
    final String possiblePassword = dictionaryEntry; 
    bufferPutTo.put(dictionaryEntry); 
    final String possiblePasswordUpperCase = dictionaryEntry.toUpperCase(); 
    bufferPutTo.put(possiblePasswordUpperCase); 
    final String possiblePasswordCapitalized = StringUtilities.capitalize(dictionaryEntry); 
    bufferPutTo.put(possiblePasswordCapitalized); 
    final String possiblePasswordReverse = new StringBuilder(dictionaryEntry).reverse().toString(); 
    bufferPutTo.put(possiblePasswordReverse); 
    for (int i = 0; i < 100; i++) { 
     final String possiblePasswordEndDigit = dictionaryEntry + i; 
     bufferPutTo.put(possiblePasswordEndDigit); 
    } 
    for (int i = 0; i < 100; i++) { 
     final String possiblePasswordStartDigit = i + dictionaryEntry; 
     bufferPutTo.put(possiblePasswordStartDigit); 
    } 
    for (int i = 0; i < 10; i++) { 
     for (int j = 0; j < 100; j++) { 
      final String possiblePasswordStartEndDigit = i + dictionaryEntry + j; 
      bufferPutTo.put(possiblePasswordStartEndDigit); 
     } 
    } 
} 
} 

버퍼 클래스 :

package passwordcracking; 

import java.util.LinkedList; 
import java.util.Queue; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* 
* @author zatokar 
*/ 
public class Buffers <T>{ 
final Queue<T> ll = new LinkedList<>(); 
int capacity=500000; 
public synchronized T take(){ 

    while (ll.isEmpty()) { 
     try { 
//    System.out.println("empty"); 
      wait(); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(Buffers.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     } 
    T element = ll.remove(); 
    notifyAll(); 
    return element; 

} 

    public synchronized void put(T element) { 
    while (isFull()) { 
     try { 

//   System.out.println("full "+element); 
      wait(); 
     } catch (InterruptedException e) { 
     } 
    } 

    ll.add(element); 
    notifyAll(); 
} 
    public boolean isFull(){ 
     return (ll.size()==capacity); 
     } 


    public boolean isEmpty(){ 
     if (ll.isEmpty()){ 
      return true; 
     } 
     else{ 
      return false;} 
    } 
} 

비교 클래스 :

패키지 passwordcracking;

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class Compare implements Runnable { 

Buffers<PairEncPWandClearPW> bufferTakeFrom; 
final List<UserInfo> userInfos; 
byte[] digest; 
PairEncPWandClearPW pair; 
String possiblePassword; 

public Compare(Buffers<PairEncPWandClearPW> bufferTakeFrom) throws IOException { 
    this.bufferTakeFrom = bufferTakeFrom; 
    userInfos = PasswordFileHandler.readPasswordFile("passwords.txt"); 
} 

@Override 
public void run() { 
    do { 
     pair=bufferTakeFrom.take(); 
     possiblePassword = pair.getClearPW(); 
     digest = pair.getEncryptedPW(); 
     List<UserInfoClearText> list = checkSingleWord(userInfos, digest, 

possiblePassword); 
     if (!list.isEmpty()) { 
      System.out.println(list); 
     } 
     if (possiblePassword.equals("-1")) { 
      System.out.println("Comparing thread finished."); 
      final long endTime = System.currentTimeMillis(); 
      final long usedTime = endTime - PasswordCracking.startTime; 
      System.out.println("Used time: " + usedTime/1000 + " seconds = " +  

usedTime/60000.0 + " minutes"); 
     } 
    } while (!possiblePassword.equals("-1")); 
} 

private List<UserInfoClearText> checkSingleWord(final List<UserInfo> userInfos, final  

byte[] digest, final String possiblePassword) { 
    final List<UserInfoClearText> results = new ArrayList<UserInfoClearText>(); 
    for (UserInfo userInfo : userInfos) { 
     if (Arrays.equals(userInfo.getEntryptedPassword(), digest)) { 
      results.add(new UserInfoClearText(userInfo.getUsername(),  

possiblePassword)); 
     } 
    } 
    return results; 
} 
} 
+2

"잘못 했으니까요"좀 더 심층적 인 대답을 위해 코드를 게시하십시오. – TwoThe

+0

고맙습니다. 여기에서 당신은 제가 실수를 찾는 데 너무 많은 시간을 할애 해 주셨으면합니다. 인터넷 검색 등등. –

+0

문제가 버퍼 크기에 있음을 알게되었습니다. 나는 생성자를 만들었고 버퍼의 용량이 바뀌면서 시간이 바뀌고있다. 예 : 변형 버퍼의 크기가 1500보다 크면 시간은 더 길지 만 용량이 1000 이하이면 보이지 않습니다. 성공적인 메시지 작성. –

답변

0

자신의 버퍼 클래스 대신 SynchronousQueue을 사용해보십시오. 나는 이것이 귀하의 동기식 구현으로 인해 주요 속도 개선이 될 것이라고 확신합니다.

이외의 아키텍처는 의심 스럽습니다. SynchroneousQueue는 생성 스레드가 처리 스레드를 오버플로/언더 플로우하지 않도록 유지해야합니다. 왜 이러한 처리 스레드가 자체 작업을 생성하지 않습니까?

사전에서 한 단어를 취하여 변형을 생성 한 다음 실제 비밀번호와 비교하여 테스트 할 수있는 Runnable을 작성할 수 있습니다. 이렇게하면 코드가 단순해질뿐 아니라 실제 스레드에서 스레드가 100 % 작동하고 스레드에서 쓰레드가 얼마나 많은지 걱정할 필요가 없습니다.

+0

답변을 주셔서 감사합니다 내가 하나의 runnable에 쓰기 가능하고 어쩌면 그것은 똑똑하지만 우리의 아키텍처는 바운드 버퍼를 사용하고 불행히도 그 스레드를 사용하는 것입니다 때문에 synchronousqueue하려고합니다. 고마워요. 곧 답변을 받아 들일 수있게 되길 바랍니다. :) –

0

Okey 너무 감사합니다. 그는 거의 내 문제를 완전히 해결했습니다. 주요 속도는 LinkedList 큐를 LinkedBlockingQueue로 대체하는 것입니다 (그는 SynchronousQueue를 사용하기 위해 응답했으나 구현 된 용량 생성자가 없습니다). 용량 생성자와 함께 사용되는 것은 변형을 만들고 LinkedList에 넣기 때문에 필요합니다. OutOfMemoryException를 얻는다. 순전히 속도가 3 배 적어서 고맙습니다. 문제는 버퍼 클래스에서 내 자신의 동기화했다.

+0

나는 이것을 초기 게시물에 넣었지만 언더 플로우/오버 플로우 문제를 파악하고 SynchroneousQueue로 대체했습니다. 아무 래도 입력을 제한하면 다른 하나는 잘 작동합니다. ;) – TwoThe