Skip to content

Instantly share code, notes, and snippets.

@Cairnarvon
Created May 26, 2011 21:20
Show Gist options
  • Save Cairnarvon/994114 to your computer and use it in GitHub Desktop.
Save Cairnarvon/994114 to your computer and use it in GitHub Desktop.
Distributed tripcode finder using Open MPI.
/* mpicc -lssl -o tripfind tripfind.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <regex.h>
#include <signal.h>
#include <sys/time.h>
#include <openssl/des.h>
#include <mpi.h>
#define SYNC_RATE 1 /* How often processes report statistics back to process 0 */
char *tripcode(const char*, char*);
void report(int);
void done(int);
typedef struct { char code; char body[11]; unsigned int n; } MESS;
enum {T_TRIP, T_SYNC, T_END};
struct timeval t_begin, t_end;
unsigned long tot = 0;
int main(int argc, char *argv[])
{
int rank;
regex_t preg;
int cflags = REG_EXTENDED | REG_NOSUB /* | REG_ICASE */;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (regcomp(&preg, argv[argc - 1], cflags) != 0) {
if (rank == 0) {
fprintf(stderr, "Invalid regex: %s. Terminating.\n", argv[argc - 1]);
}
MPI_Finalize();
return 2;
}
if (argc < 2) {
if (rank == 0) {
fprintf(stderr, "Needs argument.\n");
}
MPI_Finalize();
return 3;
}
if (rank == 0) {
int num_tasks;
MPI_Comm_size(MPI_COMM_WORLD, &num_tasks);
if (num_tasks < 2) {
fprintf(stderr, "Needs at least two processes to be useful.\n");
MPI_Finalize();
return 1;
}
signal(SIGUSR1, *report);
signal(SIGINT, *done);
gettimeofday(&t_begin, NULL);
for (;;) {
char buf[15], trip[14];
MESS m;
MPI_Recv(buf, sizeof(MESS), MPI_CHAR,
MPI_ANY_SOURCE, 1, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
m = *(MESS*)buf;
if (m.code == T_TRIP)
printf("%s\t!%s\n", m.body, tripcode(m.body, trip));
else if (m.code == T_SYNC) {
tot += m.n;
gettimeofday(&t_end, NULL);
} else
if (--num_tasks < 2) break;
}
} else {
char buffa[9], trip[14];
const char set[] = "!$%'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQR"
"STUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
int setsize = sizeof(set);
unsigned int checked = 0;
time_t last;
signal(SIGUSR1, SIG_IGN);
buffa[8] = 0;
srandom(rank);
time(&last);
for (;;) {
int i;
char *turippu;
time_t cur;
for (i = 0; i < 8; ++i) {
buffa[i] = set[((unsigned int)random()) % setsize];
}
turippu = tripcode(buffa, trip);
if (regexec(&preg, turippu, 0, NULL, 0) == 0) {
MESS m;
m.code = T_TRIP;
strncpy(m.body, buffa, 10);
MPI_Send(&m, sizeof(MESS), MPI_CHAR, 0, 1, MPI_COMM_WORLD);
}
++checked;
time(&cur);
if (cur - last >= SYNC_RATE) {
MESS m;
m.code = T_SYNC;
m.n = checked;
MPI_Send(&m, sizeof(MESS), MPI_CHAR, 0, 1, MPI_COMM_WORLD);
checked = 0;
last = cur;
}
}
}
MPI_Finalize();
return 0;
}
char *tripcode(const char *in, char *out)
{
const char *salt = "................................"
".............../0123456789ABCDEF"
"GABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
"fabcdefghijklmnopqrstuvwxyz.....";
char s[2];
s[0] = salt[(int)in[1]];
s[1] = salt[(int)in[2]];
DES_fcrypt(in, s, out);
out[13] = 0;
return out + 3;
}
void report(int _)
{
time_t sec;
suseconds_t usec;
(void)_;
sec = t_end.tv_sec - t_begin.tv_sec;
usec = 1000000 - t_begin.tv_usec + t_end.tv_usec;
if (usec > 1000000) {
usec -= 1000000;
++sec;
}
printf("%d tripcodes examined in %d.%03d seconds (%d per second).\n",
(unsigned int)tot, (int)sec, (int)(usec / 1000), (int)(tot / sec));
}
void done(int _)
{
report(_);
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment