您确实意识到,如果您提供一个整数密码值(例如 55673),并且如果您在循环中一次一个地遍历每个值,那么您不需要应用程序来确定密码编号尝试获取该密码的次数(55673 次迭代)。我们只是把它作为一个例子。 :/
在我看来,您的特定项目存在一些需要注意的问题:
为了更简单的编码,设置 BruteForce 类使其扩展 JFrame:public class BruteForce extends javax.swing.JFrame {。您不需要静态 JFrame 变量 (frameObject),它会稍微清理一下。
从 main() 方法中取出所有与 JFrame 相关的代码。请改为在 initialization 方法中设置 JFrame。在我看来,我认为你的 main() 方法会更好,如果你有:
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BruteForce().setVisible(true);
}
});
}
您的初始化方法可能如下所示:
private void initializeComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Brute Force Tool");
setResizable(false);
setAlwaysOnTop(true);
// Size the Form
// Slightly different from original size since
// form has been made non-resizable. Makes the
// form more uniformed.
setPreferredSize(new Dimension(285, 325));
setSize(getPreferredSize());
// Center Form to screen. Should always be after sizing
setLocationRelativeTo(null);
panelObject = new JPanel();
panelObject.setLayout(null);
// Password Box Label
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword = new JLabel("Password: ");
lblPassword.setBounds(10, 10, 100, 30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
// Password Entry Text Field
txtPassword = new JTextField();
txtPassword.setBounds(80, 10, 190, 30);
panelObject.add(txtPassword);
// Text Area with Scroll Pane to display
// Brute Force process.
txtStatus = new JTextArea("Status: ");
scrollbar = new JScrollPane(txtStatus);
scrollbar.setBounds(10, 125, 260, 160);
panelObject.add(scrollbar);
// Button to start Brute Force Process
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
// Display Progress CheckBox
chkUpdateStatus = new JCheckBox("Display Progress");
chkUpdateStatus.setBounds(10, 85, 150, 30);
panelObject.add(chkUpdateStatus);
// Scroll Progress CheckBox
chkScrollUpdate = new JCheckBox("Scroll Progress");
chkScrollUpdate.setBounds(160, 85, 150, 30);
panelObject.add(chkScrollUpdate);
// Add filled JPanel to JFrame
panelObject.setBounds(this.getBounds());
getContentPane().add(panelObject);
// Add Button Action Listener
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!workThreadIsRunning) {
// Clear the TextArea
txtStatus.setText(null);
new Thread(workThread).start();
}
if (btn.getText().equals("Cancel Test")) {
shutDownThread = true;
}
}
});
}
这意味着您的类构造函数 (BruteForce()) 仅包含:
public BruteForce() {
initializeComponents();
}
如果您不打算使用 JFrame#pack() 以便 JFrame 根据其所有内容自动调整大小,等于或大于其首选大小,则 setSize() 自行调整 JFrame 大小的方法对您没有多大帮助。在这种情况下,您还需要使用 setPreferredSize() 方法。
创建表单时,您希望将 JTextArea 添加到 JScrollPane,而不是 JPanel。然后它将是您添加到 JPanel 中的 JScrollPane。
JTextArea 的 setBounds() 不是必需的,因为它将填充整个 JScrollPane 容器。对于您使用的 null 布局,它将是需要提供 setBounds() 的 JScrollPane。
由于您使用的是 Null 布局并且您的应用程序窗口是
确实足够小,并且您已经为所有组件设置了边界,您还应该确保无法调整 JFrame 窗口的大小(setResizable(false);),因为如果是这样,表单看起来会很荒谬。我相信您已经被告知了为什么 Null 布局不一定是一个好的选择。但如果这对你来说还不够,那么谷歌这个:Why is null layout in Swing frowned upon?。然而,它确实在世界上占有一席之地,尤其是在使用多种布局时。
附带说明:
可以理解,在处理这样的事情时,通常很高兴在执行过程中看到该过程的进度。可悲的现实是,在尝试这样做时,速度会严重受到阻碍。
要通过在 JTextArea 上附加一行指示已处理的暴力尝试(迭代)来有效更新 JTextArea,您需要使用新线程来执行该更新。这当然意味着处理(尝试)是在单独的线程中执行的,而不是在事件调度线程(EDT)中完成,在所有处理完成之前不会更新 JTextArea(这就是您在代码中所做的) )。通过将处理代码放置在其自己的线程中立即更新 JTextArea 确实是唯一可行的选择,但将更新写入 JTextArea 确实需要时间......事实上相当长的时间。
例如,如果您运行下面提供的可运行代码(您的代码已修改)并提供密码 222222,在我的系统上大约需要 2147 毫秒(大约 2 秒)完成任务。如果您要在循环中注释掉 textStatus.append(...),您会发现只需要大约 6 毫秒(大约 0.006 秒)即可完成任务。这是处理时间的一个非常显着的差异,如果您正在执行类似 Brute Force 之类的操作,您希望获得每一个速度。如果您希望 JTextArea 自动滚动以便在视口中显示每个更新,那么速度会受到更多的阻碍。
进度显示应该是可选的,可以使用我在下面的示例可运行代码中实现的复选框,并且由于蛮力处理是在其自己的线程而不是 EDT 中完成的,因此对复选框的任何更改都会立即生效影响。该按钮还具有更多的切换效果,因此可以取消蛮力处理。
这是完整的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BruteForce extends javax.swing.JFrame {
JPanel panelObject;
JLabel lblPassword;
JTextField txtPassword;
JTextArea txtStatus;
JScrollPane scrollbar;
JButton btn;
JCheckBox chkUpdateStatus;
JCheckBox chkScrollUpdate;
Runnable workThread;
boolean workThreadIsRunning = false;
volatile boolean shutDownThread = false;
public BruteForce() {
initializeComponents();
workThread = new Runnable() {
@Override
public void run() {
long startTime = System.currentTimeMillis();
workThreadIsRunning = true;
int password = Integer.parseInt(txtPassword.getText());
btn.setText("Cancel Test");
int guess_password = 0;
while (guess_password != password & !shutDownThread) {
if (chkUpdateStatus.isSelected()) {
txtStatus.append("\n [+] Password Attempt: " + String.valueOf(guess_password + 1));
if (chkScrollUpdate.isSelected()) {
// Update The JTextArea to show immediate processing.
// (Slows down processing considerably)
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
}
guess_password++;
}
long duration = System.currentTimeMillis() - startTime;
if (guess_password == password) {
txtStatus.append("\n \n [-] Password Found: " + guess_password);
txtStatus.append("\n [-] It took " + duration + " milliseconds\n "
+ "(just over " + String.valueOf(duration / 1000) + " seconds) "
+ "to\n accomplish.");
txtStatus.setCaretPosition(txtStatus.getText().length() - 1);
}
workThreadIsRunning = false;
btn.setText("Test Password Strength");
shutDownThread = false;
}
};
}
private void initializeComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Brute Force Tool");
setResizable(false);
setAlwaysOnTop(true);
// Size the Form
// Slightly different from original size since
// form has been made non-resizable. Makes the
// form more uniformed.
setPreferredSize(new Dimension(285, 325));
setSize(getPreferredSize());
// Center Form to screen. Should always be after sizing
setLocationRelativeTo(null);
panelObject = new JPanel();
panelObject.setLayout(null);
// Password Box Label
Font dialog = new Font("Dialog", Font.PLAIN, 14);
lblPassword = new JLabel("Password: ");
lblPassword.setBounds(10, 10, 100, 30);
lblPassword.setFont(dialog);
panelObject.add(lblPassword);
// Password Entry Text Field
txtPassword = new JTextField();
txtPassword.setBounds(80, 10, 190, 30);
panelObject.add(txtPassword);
// Text Area with Scroll Pane to display
// Brute Force process.
txtStatus = new JTextArea("Status: ");
scrollbar = new JScrollPane(txtStatus);
scrollbar.setBounds(10, 125, 260, 160);
panelObject.add(scrollbar);
// Button to start Brute Force Process
btn = new JButton("Test Password Strength");
btn.setBounds(10, 50, 260, 30);
panelObject.add(btn);
// Display Progress CheckBox
chkUpdateStatus = new JCheckBox("Display Progress");
chkUpdateStatus.setBounds(10, 85, 150, 30);
panelObject.add(chkUpdateStatus);
// Scroll Progress CheckBox
chkScrollUpdate = new JCheckBox("Scroll Progress");
chkScrollUpdate.setBounds(160, 85, 150, 30);
panelObject.add(chkScrollUpdate);
// Add filled JPanel to JFrame
panelObject.setBounds(this.getBounds());
getContentPane().add(panelObject);
// Add Button Action Listener
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!workThreadIsRunning) {
// Clear the TextArea
txtStatus.setText(null);
new Thread(workThread).start();
}
if (btn.getText().equals("Cancel Test")) {
shutDownThread = true;
}
}
});
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new BruteForce().setVisible(true);
}
});
}
}