下面的简单项目使用java并发实现暴力算法。此版本的代码尝试查找仅包含数字的密码(0-9)通过数字算法会自动增加字符串中可能是需要查找的潜在密码的位数。
我在寻找什么。 我想以可能导致死锁的方式更改代码,以便了解错误和正确的方法。另外,我想在调试模式下玩这个死锁。而且,如果你向我展示这种僵局的解决方案,那就太棒了。请告诉我添加到代码中的内容是为了接收死锁以及这种死锁的解决方案是什么? 第一个暴力项目的代码
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...");
}
}
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();
}
}
非常感谢提前!正如你可以看到这个蛮力的例子没有任何锁。因此,据我所知,很难对此代码造成僵局。但是,我发现了暴力执行的另一个实现,显然并且不幸的是它更复杂,因为它使用GUI和SHA-1。我没有时间摆脱那些并发症,所以请事先原谅我。但是,据我所知,第二个项目将更适合死锁演示,因为它不是通过ExecutionService接口而是通过使用锁和同步方法来执行多线程。请看一下。 (下面的代码)如果我搞砸了这个基本条款,请原谅我的最终的无聊和#34;在给定的主题。我真的没有多少地方和时间来推进我在java并发方向上的知识,但是现在我需要这种知识,这是前所未有的。
下面的第二个暴力项目的代码。
// *****************************************
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;
}
}
}