Java 关于暴力攻击的死锁示例
下面的简单项目使用java并发实现暴力算法。此版本的代码尝试查找仅包含数字(0-9)的密码。通过数字,算法会自动增加字符串中可能是需要查找的潜在密码的位数 我在找什么。 我想以一种可能出现死锁的方式修改代码,以便理解什么是错的,什么是对的。另外,我想在调试模式下处理这个死锁。此外,如果你能告诉我解决这个僵局的方法,那就太好了。请告诉我为了接收死锁而向代码中添加了什么,以及该死锁的解决方案是什么? 第一个暴力项目的代码如下Java 关于暴力攻击的死锁示例,java,multithreading,synchronization,deadlock,brute-force,Java,Multithreading,Synchronization,Deadlock,Brute Force,下面的简单项目使用java并发实现暴力算法。此版本的代码尝试查找仅包含数字(0-9)的密码。通过数字,算法会自动增加字符串中可能是需要查找的潜在密码的位数 我在找什么。 我想以一种可能出现死锁的方式修改代码,以便理解什么是错的,什么是对的。另外,我想在调试模式下处理这个死锁。此外,如果你能告诉我解决这个僵局的方法,那就太好了。请告诉我为了接收死锁而向代码中添加了什么,以及该死锁的解决方案是什么? 第一个暴力项目的代码如下 package bfpasswrd_multi; import j
package bfpasswrd_multi;
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
System.out.print("Type password to be cracked: ");
@SuppressWarnings("resource")
String input = new Scanner(System.in).nextLine();
PasswordCracker cracker = new PasswordCracker();
System.out.println("Multithreaded");
cracker.runMulti(input);
cracker = new PasswordCracker();
System.out.println("Finished...");
}
}
包bfpasswrd\u multi;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
公共类密码破解器
{
字符串密码跟踪;
找到公共布尔密码;
int-min;
int max;
StringBuffer破解密码;
公共空白准备(字符串文本)
{
PasswordToTrack=文本;
passwordFound=false;
最小值=48;
最大值=57;//http://ascii.cl/
crackedPassword=新的StringBuffer();
crackedPassword.append((char)(min-1));
}
公开结果()
{
System.out.println(“破解密码为:+crackedPassword.toString());
}
public void incrementString(StringBuffer-torack,int-min,int-max)
{
toCrack.setCharAt(0,(char)((int)toCrack.charAt(0)+1));
对于(int i=0;i最大字符数)
{
toCrack.setCharAt(i,(char)min);
if(toCrack.length()==i+1)
{
toTrack.append((char)min);
}
其他的
{
toCrack.setCharAt(i+1,(char)((int)toCrack.charAt(i+1)+1));
}
}
}
}
公共void runMulti(字符串文本)
{
编写(文本);
double time=System.nanoTime();
doItMulti();
时间=System.nanoTime()-时间;
系统输出打印项次(时间/(100000000));
结果();
}
public void doItMulti()
{
int cores=Runtime.getRuntime().availableProcessors();
ArrayList>(cores));
ExecutorService executor=Executors.newFixedThreadPool(核心);
最后一个长步长=2000;
对于(长i=0;i核心)
{
对于(int w=0;w长最大值-最小值)
{
数字=长。最大值-最小值;
}
ArrayList向量=新的ArrayList(10);
矢量加(最小值-1+数字);
远程=最大-最小+1;
布尔nextLetter=false;
对于(int i=0;imax)
{
nextLetter=true;
长乘法器=Math.abs(vector.get(i)/range);
if((向量get(i)-(乘法器*范围))
非常感谢!正如您可以看到的,这个暴力示例没有任何锁。因此,据我所知,这段代码很难死锁。然而,我发现了蛮力执行的另一个实现,它显然更复杂,不幸的是,因为它使用GUI和SHA-1。我没有时间解决这些复杂问题,所以请提前原谅我。但是,据我所知,第二个项目更适合死锁演示,因为它不是通过ExecutionService接口而是通过使用来执行多线程
package bfpasswrd_multi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PasswordCracker
{
String passwordToCrack;
public boolean passwordFound;
int min;
int max;
StringBuffer crackedPassword;
public void prepare(String text)
{
passwordToCrack = text;
passwordFound = false;
min = 48;
max = 57; // http://ascii.cl/
crackedPassword = new StringBuffer();
crackedPassword.append((char) (min - 1));
}
public void result()
{
System.out.println("Cracked Password is: " + crackedPassword.toString());
}
public void incrementString(StringBuffer toCrack, int min, int max)
{
toCrack.setCharAt(0, (char) ((int) toCrack.charAt(0) + 1));
for (int i = 0; i < toCrack.length(); i++)
{
if (toCrack.charAt(i) > (char) max)
{
toCrack.setCharAt(i, (char) min);
if (toCrack.length() == i + 1)
{
toCrack.append((char) min);
}
else
{
toCrack.setCharAt(i + 1, (char) ((int) toCrack.charAt(i + 1) + 1));
}
}
}
}
public void runMulti(String text)
{
prepare(text);
double time = System.nanoTime();
doItMulti();
time = System.nanoTime() - time;
System.out.println(time / (1000000000));
result();
}
public void doItMulti()
{
int cores = Runtime.getRuntime().availableProcessors();
ArrayList<Future<?>>(cores));
List<Future<?>> futures ;
futures = Collections.synchronizedList(new ArrayList<Future<?>>(cores));
ExecutorService executor = Executors.newFixedThreadPool(cores);
final long step = 2000;
for (long i = 0; i < Long.MAX_VALUE; i += step)
{
while(futures.size() > cores)
{
for(int w = 0; w < futures.size();w++)
{
if(futures.get(w).isDone())
{
futures.remove(w);
break;
}
}
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
{
final long j = i;
if (passwordFound == false)
{
futures.add(executor.submit(new Runnable()
{
public void run()
{
long border = j + step;
StringBuffer toCrack = new StringBuffer(10);
toCrack.append(constructString3(j, min, max));
for (long k = j; k < border; k++)
{
incrementString(toCrack, min, max);
boolean found = toCrack.toString().equals(passwordToCrack);
if (found)
{
crackedPassword = toCrack;
passwordFound = found;
break;
}
}
}
}));
}
else
{
break;
}
}
}
executor.shutdownNow();
}
public String constructString3(long number, long min, long max)
{
StringBuffer text = new StringBuffer();
if (number > Long.MAX_VALUE - min)
{
number = Long.MAX_VALUE - min;
}
ArrayList<Long> vector = new ArrayList<Long>(10);
vector.add(min - 1 + number);
long range = max - min + 1;
boolean nextLetter = false;
for (int i = 0; i < vector.size(); i++)
{
long nextLetterCounter = 0;
while (vector.get(i) > max)
{
nextLetter = true;
long multiplicator = Math.abs(vector.get(i) / range);
if ((vector.get(i) - (multiplicator * range)) < min)
{
multiplicator -= 1;
}
vector.set(i, vector.get(i) - (multiplicator * range));
nextLetterCounter += multiplicator;
}
if (nextLetter)
{
vector.add((long) (min + nextLetterCounter - 1));
nextLetter = false;
}
text.append((char) vector.get(i).intValue());
}
return text.toString();
}
}
// *****************************************
package pl.scriptease.studia.prir;
import java.security.MessageDigest;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BruteForce extends Thread {
public static Object lock = new Object();
public static GUI gui;
static String sha1 = "";
static int length = 1;
static int numberOfThreads = 1;
private static int nextThreadId = 1;
static String textAreaBuffer = "";
static String password = "";
static ExecutorService executor;
static Set<Thread> threadSet;
volatile boolean running = false;
boolean foundPassword = false;
int threadId = 0;
long startTime;
long endTime;
long elapsedTime;
String start;
String temporary;
String end;
static char[] searcharea = "0123456789abcdefghijklmnopqrstuwxyz".toCharArray();
void loop() {
temporary = start;
while (running) {
// print(this + " checking: " + temp);
if (check(temporary)) {
foundPassword = true;
password = temporary;
gui.passwordFound(password);
print("password was found: '" + temporary + "'");
this.interrupt();
shutdown();
break;
}
temporary = search(temporary);
if (interrupted()) {
break;
}
if (temporary.length() > length) {
break;
}
if (temporary.length() >= length && temporary.startsWith(end) && end.charAt(0) != last()) {
break;
}
}
running = false;
}
public String search(String temp) {
String sample = "";
int length = temp.length();
char[] a = temp.toCharArray();
for (int i = length - 1; i >= 0; i--) {
if (i == 0) {
if (a[i] == end.charAt(0)) {
a[i] = start.charAt(0);
sample = new String(a) + first();
break;
}
}
a[i] = next(a[i]); // next character to match with original password
if (a[i] != first()) {
sample = new String(a);
break;
} else {
if (i == 0) {
sample = new String(a) + first();
}
}
}
return sample;
}
private static char next(char ch) {
if (ch == searcharea[searcharea.length - 1]) {
return searcharea[0];
} else {
return searcharea[indexOf(ch) + 1];
}
}
static boolean check(String s) {
return toSha1(s).equals(sha1);
} // compare SHA codes
static char first() {
return searcharea[0];
}
static char last() {
return searcharea[searcharea.length - 1];
}
static int indexOf(char c) {
for (int i = 0; i < searcharea.length; ++i) {
if (searcharea[i] == c) {
return i;
}
}
return -1;
}
BruteForce(String start, String end) {
this.start = start;
this.end = end;
threadId = nextThreadId;
++nextThreadId;
} // Gives Id to the threads that we later will see on the log window
public void run() {
print("started on interval [" + start + ", " + end + "]");
startTime = System.currentTimeMillis();
running = true;
loop();
endTime = System.currentTimeMillis();
elapsedTime = endTime - startTime;
print(String.format("ended with time: %.2f sec", elapsedTime / 1e3));
}
public String toString() {
return "[T" + threadId + "]";
} // return name of the thread that do the job in the log window
public static String toSha1(String input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
return byteArrayToHexString(md.digest(input.getBytes("UTF-8")));
} // convert password that you write down to the SHA code
catch (Exception e) {
return null;
}
}
private static String byteArrayToHexString(byte[] b) {
String result = "";
for (int i = 0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
public static void decrypt() {
threadSet = new HashSet<Thread>();
int searchAreaLength = searcharea.length;
int interval = (int) Math.round(searchAreaLength / numberOfThreads); // the works divided between thread equally
executor = Executors.newFixedThreadPool(numberOfThreads);
// executor = Executors.newCachedThreadPool();
for (int i = 0; i < numberOfThreads; ++i) {
int start = i * interval;
int end = (i + 1) * interval;
if (end >= searchAreaLength) {
end = searchAreaLength - 1;
}
Thread worker = new BruteForce(searcharea[start] + "", searcharea[end] + "");
executor.execute(worker);
threadSet.add(worker);
}
}
public static void shutdown() {
try {
executor.shutdown();
nextThreadId = 1;
sleep(500);
executor.shutdownNow();
} catch (NullPointerException e) {
} catch (InterruptedException e) {
}
}
private void print(String text) {
String time = String.format("%tT: ", Calendar.getInstance());
synchronized (lock) {
textAreaBuffer += (time + this + " : " + text + "\n");
}
}
public static String pullTextAreaBuffer() {
synchronized (lock) {
String ret = textAreaBuffer;
textAreaBuffer = "";
return ret;
}
}
}