如何将一个值从一个Thread返回到另一个类

时间:2016-09-15 13:58:27

标签: java multithreading hash

我目前正在编写一个Java应用程序来对MD5哈希进行强力攻击。我制作了一个采用哈希输入的JFrame。

Picture 1

例如,我将单词"密码"到MD5。 (点击图片1)点击JButton时 它会将哈希发送到比较类,该类将按顺序迭代所有可能性。 IE来自AAAAAAAA。然后到AAAAAAAB等。并哈希他们。如果可能性的散列与单词"密码"的散列匹配。将出现一个对话框,通知用户已找到匹配项。

我的问题是,我不知道如何在不使用setter和getter的情况下将implements Runnable类中的线程中的值返回给GUI类。

public void actionPerformed(ActionEvent e)
{
    if(e.getSource().equals(bruteForceButton))
    {
        enterLabel.setText("Brute force in process");

        String enteredHash = input.getText();
        int lengthOfPass = (int) length.getSelectedItem();

        //Send the information to the comparative class
        HashComparative comp = new HashComparative();
        comp.setHash(enteredHash);
        comp.setLengthOfPass(lengthOfPass);
        Thread t1 = new Thread(comp);

        t1.start();
        hash.setText(comp.getHash());
    }

这启动了将相应数据发送到比较类的线程。 这是另一个班级。

public class HashComparative implements Runnable
{

    private String h;
    private int l;
    private Thread thread;


    public void start()
    {
        thread = new Thread(this, "");
        thread.start();
    }
    @Override
    public void run() 
    {   
        try
        {
            //CODE WILL GO HERE TO COMPUTE HASHES 

            setHash(h);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }   

    public void setHash(String h)
    {
        this.h = h;
    }
    //Returns the hash currently being compared
    public String getHash()
    {
        return h;
    }
}

蛮力运作期间。我想通过将哈希字符串发送回GUI类并将文本设置为JLabel来显示它尝试的哈希值。例如

Picture 2

我已经在线查看但无法找到答案。任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

您需要实现的是Callable而不是Runnable,因为此接口允许您返回您想要的值。由于您只能向Runnable提供Thread,因此您需要使用池线程,您可以从Executors创建。它允许您submit Callable作为RunnableExecutorService executor = Executors.newSingleThreadExecutor(); ... ,然后获得Future,以便能够等到任务成功完成。

在您的情况下,您可以使用Executors.newSingleThreadExecutor()

创建仅包含一个线程的池
HashComparative

然后您的班级public class HashComparative implements Callable<String> { private final String enteredHash; private final int lengthOfPass; public HashComparative(final String enteredHash, final int lengthOfPass) { this.enteredHash = enteredHash; this.lengthOfPass = lengthOfPass; } @Override public String call() throws Exception { //CODE WILL GO HERE TO COMPUTE HASHES return h; } ... } 将是:

HashComparative comp = new HashComparative(enteredHash, lengthOfPass);
Future<String> future = executor.submit(comp);
hash.setText(future.get());

最后,您将提交下一个任务:

HashComparative
  

可以用什么来显示不匹配的哈希?

与此类需求相匹配的最佳设计模式是Observer。确实,您希望在UI中观察计算的进度。开箱即用,您可以使用ObservableObserver来实现此模式。

因此,为了简单起见,您可以让您的班级Observable扩展Observers,以便能够在新哈希出现时随时通知public class HashComparative extends Observable implements Callable<String> { private String h; ... public void setHash(String h) { this.h = h; setChanged(); notifyObservers(); } public String getHash() { return h; } } (您的用户界面)处理。

Observer

然后,在您的用户界面中,您可以通过实施final HashComparative comp = new HashComparative(enteredHash, lengthOfPass); comp.addObserver(new Observer() { @Override public void update(final Observable o, final Object arg) { HashComparative hc = (HashComparative)o; hash.setText(hc.getHash()); } });

来相应地更改文字
Executors.newSingleThreadScheduledExecutor()

如果速度过快,您还可以使用ScheduledExecutorService仅更改在给定时间后显示的哈希值。例如,您可以使用final HashComparative comp = new HashComparative(enteredHash, lengthOfPass); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { hash.setText(comp.getHash()); } }, 1L, 1L, TimeUnit.SECONDS); 创建它,只有一个线程然后刷新下一个哈希:

Observable

这将刷新每秒显示的哈希值。使用这种方法,您不再需要扩展h,您只需要生成volatile public class HashComparative implements Callable<String> { private volatile String h; ... } ,因为它将被多个线程同时修改和访问

array([[   2.8],
       [ 206. ],
       [  84.4],
       [ 297.6],
       [ 112.7],
       [ 235.4],
       [ 170.7],
       [  22.2],
       [ 264.1],
       [ 163.2],
       [  43.7],
       [ 131.2]])
Result = [0, 7, 10]