Skip to content

Commit 1fe7942

Browse files
authored
Add files via upload
1 parent e7cb223 commit 1fe7942

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

pdc.cpp

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <map>
2+
#include <omp.h>
3+
#include <mpi.h>
4+
#include <string>
5+
#include <vector>
6+
#include <crypt.h>
7+
#include <fstream>
8+
#include <string.h>
9+
#include <unistd.h>
10+
#include <iostream>
11+
12+
#include "crack.cpp"
13+
14+
using namespace std;
15+
16+
int main(int argc, char** argv)
17+
{
18+
// driver code for the program -> responsible for starting the processes, distributing the alphabet among them, calling on them to search for the password,
19+
// print the password once it is cracked, and then terminate all processes and end program
20+
21+
int rank, nprocs;
22+
23+
// MPI initialisation
24+
MPI_Init(&argc, &argv);
25+
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
26+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
27+
28+
// master specific code
29+
if (rank == 0) {
30+
cout << "master: there are " << nprocs - 1 << " slave processes" << endl;
31+
32+
string username = "project";
33+
34+
string salt_hash = get_salt_hash("/mirror/shadow.txt", username); // parse file and extract the salt + hash for the specified username
35+
36+
if (salt_hash.empty()) {
37+
cout << "File was not opened, terminating program." << endl;
38+
MPI_Abort(MPI_COMM_WORLD, 0); // terminates all MPI processes associated with the mentioned communicator (return value 0)
39+
exit(0); // just in case :)
40+
}
41+
42+
map<int, string> distrib = divide_alphabet(nprocs-1); // getting the alphabet division per process (including master, if required)
43+
44+
// send salt_hash and the letters assigned to that process to every slave
45+
for (int i = 1; i < nprocs; i++) {
46+
MPI_Send(salt_hash.c_str(), 200, MPI_CHAR, i, 100, MPI_COMM_WORLD); // send the salt + hash string to every slave
47+
MPI_Send(distrib[i].c_str(), 30, MPI_CHAR, i, 101, MPI_COMM_WORLD); // send every slave their allocated characters
48+
}
49+
50+
// some characters have been allotted to master
51+
if (distrib[0].length() > 0) {
52+
string letters = distrib[0];
53+
cout << "master: " << letters << endl;
54+
55+
// master needs two threads running in parallel here
56+
// one to search through its own assigned characters
57+
// one to wait in case any slave cracks the password and reports to master
58+
#pragma omp parallel num_threads(2)
59+
{
60+
// 1st thread: search through the permuations of it's letters
61+
if (omp_get_thread_num() == 0) {
62+
// go through its assigned characters -> for every character, call the cracking function on it
63+
for (int i = 0; i < letters.length(); i++) {
64+
password_cracker(letters[i], salt_hash);
65+
}
66+
}
67+
68+
// 2nd thread: wait for slave to find the answer instead
69+
// note: even if master finds the password, it also sends a signal back to itself (and recieves it here)
70+
else {
71+
char password[10];
72+
73+
MPI_Status status;
74+
MPI_Recv(password, 10, MPI_CHAR, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status); // blocking recieve waiting for any process to report
75+
76+
cout << "Process " << status.MPI_SOURCE << " has cracked the password: " << password << endl;
77+
cout << "Terminating all processes" << endl;
78+
79+
MPI_Abort(MPI_COMM_WORLD, 0); // terminates all MPI processes associated with the mentioned communicator (return value 0)
80+
// this is not a graceful way of exiting but will suffice for the functionality we require
81+
}
82+
}
83+
}
84+
85+
// in this case, the characters have been divided equally among the slaves
86+
// master has nothing to do except wait for a slave to report password found
87+
else {
88+
char password[10];
89+
90+
MPI_Status status;
91+
MPI_Recv(password, 10, MPI_CHAR, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status); // blocking recieve waiting for any process to report
92+
93+
cout << "Process " << status.MPI_SOURCE << " has cracked the password: " << password << endl;
94+
cout << "Terminating all processes" << endl;
95+
96+
MPI_Abort(MPI_COMM_WORLD, 0); // terminates all MPI processes associated with the mentioned communicator (return value 0)
97+
// this is not a graceful way of exiting but will suffice for the functionality we require
98+
}
99+
}
100+
101+
// slave specific code
102+
else {
103+
char salt_hash[200], letters[30];
104+
105+
MPI_Recv(salt_hash, 200, MPI_CHAR, 0, 100, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // recieve salt_hash (same for every slave)
106+
MPI_Recv(letters, 200, MPI_CHAR, 0, 101, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // recieve allotted characters (different for every slave)
107+
108+
cout << "slave " << rank << ": " << letters << endl;
109+
110+
sleep(2); // this is just to ensure all slaves print their allotted characters then start execution (for neatness :) )
111+
112+
// go through its assigned characters -> for every character, call the cracking function on it
113+
for (int i = 0; i < charToString(letters).length(); i++) {
114+
password_cracker(letters[i], charToString(salt_hash));
115+
}
116+
}
117+
118+
MPI_Finalize();
119+
120+
return 0;
121+
}

0 commit comments

Comments
 (0)