@ Pohon BBS

tripex tripcode finding software

Go back: thread mode | tree mode | sub tree

#8.
Published: 2025-08-31 [Sun] 16:56, by taocana◆PhREAk.tEk
fully patched up2date src for convenience :^)

----BEGIN FILE tripex.c----
/* CC0-1.0 */

#include <err.h>
#include <crypt.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/random.h>

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#define MAX_EXPRS 262144

static unsigned char saltFilter[256];
static unsigned char rngFilter[256];
char *tripcode(const char *key);

/* if i put this garbage on the stack instead of bss, it will segfault. */
size_t n_exprs = 0;
regex_t exprs[MAX_EXPRS];

void usage(void)
{
fprintf(stderr, "usage: tripex [-Ef:hil:n:m:s:v] expressions\n"
" -E\tuse extended regular expressions\n"
" -f\tread expressions from file (use '-' for stdin)\n"
" -h\tshow usage\n"
" -i\tignore case\n"
" -l\tkey length\n"
" -n\tnumber of threads\n"
" -m\tmax number of tries (per thread!)\n"
" -s\tstack (logical AND) expressions before/after expr #n (negative for before)\n");
}

void appendExpr(regex_t exprs[], size_t *i, char *str, int re_flags)
{
/* avoiding malloc like the plague, simple and fast shitware!
* if you somehow need more than MAX_EXPRS, change it & recompile.
*/
if (*i >= MAX_EXPRS)
errx(EXIT_FAILURE, "no %s-kun! it's too many exprs, it wont fit!", getlogin());
if (regcomp(&exprs[*i], str, re_flags))
errx(EXIT_FAILURE, "failed to compile regex '%s'", str);
(*i)++;
}

int main(int argc, char *argv[])
{
int re_flags = 0;
int sflag = 0;
long stack_after = 0;
size_t n_procs = 1;
size_t key_len = 10;
size_t max_tries = 0;

int opt;
while ((opt = getopt(argc, argv, "E:f:hil:m:M:n:s:v")) != -1) {
switch(opt) {
case 'E':
re_flags |= REG_EXTENDED;
break;
case 'f':
FILE *fp = stdin;
if (strcmp(optarg, "-") != 0)
fp = fopen(optarg, "r");
if (!fp)
err(EXIT_FAILURE, "couldn't open regex file '%s'", optarg);

char *line = NULL;
size_t len = 0;
ssize_t nread;
while ((nread = getline(&line, &len, fp)) != -1) {
*strchr(line, '\n') = '\0';
appendExpr(exprs, &n_exprs, line, re_flags);
}

free(line);
fclose(fp);
break;
case 'i':
re_flags |= REG_ICASE;
break;
case 'l':
key_len = atol(optarg);
if (key_len < 1)
errx(EXIT_FAILURE, "key length must be at least 1");
break;
case 'n':
n_procs = atol(optarg);
if (n_procs < 1)
errx(EXIT_FAILURE, "need at least one process");
break;
case 'm': /* ! PER THREAD ! */
max_tries = atol(optarg);
if (max_tries < 1)
errx(EXIT_FAILURE, "need at least one try");
break;
case 's':
sflag = 1;
stack_after = atol(optarg);
break;
case 'v':
printf("tripex 1.2 by taocana\n");
return EXIT_SUCCESS;
case 'h':
/* FALLTHROUGH */
default:
usage();
return EXIT_FAILURE;
}
}

argc -= optind;
argv += optind;

for (size_t i = 0; i < argc; i++)
appendExpr(exprs, &n_exprs, argv[i], re_flags);

if (n_exprs < 1) {
usage();
errx(EXIT_FAILURE, "need at least one expression");
}

for (int i = 1; i < n_procs; i++)
if (!fork())
break;

regmatch_t pmatch[1];
unsigned char key[key_len + 1];
key[key_len] = 0;

for (size_t n = 0; !max_tries || n < max_tries; n++) {
if (getrandom(key, key_len, 0) < 0)
err(EXIT_FAILURE, "failed to get random key");

for (int i = 0; i < key_len; i++)
key[i] = rngFilter[key[i]];

char *trip = tripcode(key);
if (!trip)
err(EXIT_FAILURE, "failed to generate tripcode");

for (size_t i = 0; i < n_exprs; i++) {
int stacking = (sflag
&& ((stack_after >= 0 && i >= stack_after)
|| (stack_after < 0 && i < -stack_after)));

if (regexec(&exprs[i], trip, ARRAY_SIZE(pmatch), pmatch, 0))
if (stacking)
break;
else
continue;
else if (!stacking || i >= n_exprs - 1) {
printf("%s %s\n", trip, key);
break;
}
}

free(trip);
}

for (size_t i = 0; i < n_exprs; i++)
regfree(&exprs[i]);
return EXIT_SUCCESS;
}

char *tripcode(const char *key)
{
/* we don't do any sjis conversion, but who cares anyway? */
if (strlen(key) == 0)
return NULL;

/* unsigned for array lookups by character */
unsigned char *tempKey = malloc(strlen(key) + 2);
if (!tempKey)
return NULL;
strcpy(tempKey, key);
strcat(tempKey, "H.");

unsigned char salt[3];
for (int i = 0; i < 3; i++)
salt[i] = saltFilter[tempKey[i+1]];
salt[2] = 0;
free(tempKey);

struct crypt_data data;
bzero(&data, sizeof(struct crypt_data));

char *tempCode = crypt_r(key, salt, &data);
unsigned char *code = malloc(strlen(tempCode) - 3);
if (!code) /* doesn't fully handle crypt_r(3) errors yet */
return NULL;
strcpy(code, tempCode + 3);
return code;
}

static unsigned char saltFilter[256] =
"................................"
".............../0123456789......"
".ABCDEFGHIJKLMNOPQRSTUVWXYZ....."
".abcdefghijklmnopqrstuvwxyz....."
"................................"
"................................"
"................................"
"................................";

/* we must get printable ascii from a random byte,
* but 256 % 94 = 68 which leaves too much skew.
* quantizing into 64 chars won't skew at all, but
* it only has 6 shannons of entropy per character.
* an 85 character quantization only skews by a
* remainder of one, which is miniscule enough and
* we average 6.41 shannons per character.
*/
static unsigned char rngFilter[256] =
"!#$%&'()*+,-./012"
"3456789:;<=>?@ABC"
"DEFGHIJKLMNOPQRST"
"UVWXYZ^abcdefghij"
"klmnopqrstuvwxyz~"
"!#$%&'()*+,-./012"
"3456789:;<=>?@ABC"
"DEFGHIJKLMNOPQRST"
"UVWXYZ^abcdefghij"
"klmnopqrstuvwxyz~"
"!#$%&'()*+,-./012"
"3456789:;<=>?@ABC"
"DEFGHIJKLMNOPQRST"
"UVWXYZ^abcdefghij"
"klmnopqrstuvwxyz~"
"~";

.

New Reply



(new)

You need to solve the captcha before you can post.


Parents

#1. tripex tripcode finding software
Published: 2025-01-05 [Sun] 00:04, by taocana◆PhREAk.tEk
releasing version 1.0 of my tripcode finding program, 'tripex'

compile the program as follows:
gcc tripex.c -o tripex -O3 -lcrypt

example #1; find tripcodes containing 'nice' (case insensitive):
./tripex -n $(nproc) -i nice

example #2; find tripcodes starting with either 'giko' or 'mona':
./tripex -n $(nproc) ^giko ^mona

example #3; find fully lowercase tripcodes with quads:
./tripex -s -n $(nproc) "^[a-z]*$" "\(.\)\1\{3,\}"

untested on anything but GNU/Linux with glibc, but it would probably work on FreeBSD too.
don't trust any update posts unless they have my tripcode or you can audit them yourself!

-----BEGIN FILE tripex.c-----
/* CC0-1.0 */

#include <err.h>
#include <crypt.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/random.h>

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

static unsigned char saltFilter[256];
static unsigned char rngFilter[256];
char *tripcode(const char *key);

void usage(void)
{
fprintf(stderr, "usage: tripex [-Ehilnmsv] expressions\n"
" -E\tuse extended regular expressions\n"
" -h\tshow usage\n"
" -i\tignore case\n"
" -l\tkey length\n"
" -n\tnumber of threads\n"
" -m\tmax number of tries (per thread!)\n"
" -s\tstack expressions (logical AND)\n");
}

int main(int argc, char *argv[])
{
int re_flags = 0;
int sflag = 0;
size_t n_procs = 1;
size_t key_len = 8;
size_t max_tries = 0;

int opt;
while ((opt = getopt(argc, argv, "E:hil:m:n:sv")) != -1) {
switch(opt) {
case 'E':
re_flags |= REG_EXTENDED;
break;
case 'i':
re_flags |= REG_ICASE;
break;
case 'l':
key_len = atol(optarg);
if (key_len < 1)
errx(EXIT_FAILURE, "key length must be at least 1");
break;
case 'n':
n_procs = atol(optarg);
if (n_procs < 1)
errx(EXIT_FAILURE, "need at least one process");
break;
case 'm': /* ! PER THREAD ! */
max_tries = atol(optarg);
if (max_tries < 1)
errx(EXIT_FAILURE, "need at least one try");
break;
case 's':
sflag = 1;
break;
case 'v':
printf("tripex 1.0 by taocana\n");
return EXIT_SUCCESS;
case 'h':
/* FALLTHROUGH */
default:
usage();

return EXIT_FAILURE;
}
}

argc -= optind;
argv += optind;

if (argc < 1) {
usage();
errx(EXIT_FAILURE, "need at least one expression");
}

size_t n_exps = argc;
regex_t *exps = malloc(sizeof(regex_t) * n_exps);
for (size_t i = 0; i < n_exps; i++)
if (regcomp(&exps[i], argv[i], re_flags))
errx(EXIT_FAILURE, "failed to compile regex");

for (int i = 1; i < n_procs; i++)
if (!fork())
break;

regmatch_t pmatch[1];
unsigned char key[key_len + 1]; /* dynamic array, bad form but i'm lazy */
key[key_len] = 0;

for (size_t n = 0; !max_tries || n < max_tries ; n++) {
if (getrandom(key, key_len, 0) < 0)
err(EXIT_FAILURE, "failed to get random key");

for (int i = 0; i < key_len; i++)
key[i] = rngFilter[key[i]];

char *trip = tripcode(key);
if (!trip)
err(EXIT_FAILURE, "failed to generate tripcode");

for (size_t i = 0; i < n_exps; i++)
if (regexec(&exps[i], trip, ARRAY_SIZE(pmatch), pmatch, 0))
if (sflag)
break;
else
continue;
else if (!sflag || i >= n_exps - 1)
printf("%s %s\n", trip, key);

free(trip);
}

for (size_t i = 0; i < n_exps; i++)
regfree(&exps[i]);
free(exps);
return EXIT_SUCCESS;
}

char *tripcode(const char *key)
{
/* we don't do any sjis conversion, but who cares anyway? */
if (strlen(key) == 0)
return NULL;

unsigned char *tempKey = malloc(strlen(key) + 2);
if (!tempKey)
return NULL;
strcpy(tempKey, key);
strcat(tempKey, "H.");

unsigned char salt[3];
for (int i = 0; i < 3; i++)
salt[i] = saltFilter[tempKey[i+1]];
salt[2] = 0;
free(tempKey);

struct crypt_data data;
bzero(&data, sizeof(struct crypt_data));

char *tempCode = crypt_r(key, salt, &data);
unsigned char *code = malloc(strlen(tempCode) - 3);
if (!code)
return NULL;
strcpy(code, tempCode + 3);
return code;
}

static unsigned char saltFilter[256] =
"................................"
".............../0123456789......"
".ABCDEFGHIJKLMNOPQRSTUVWXYZ....."
".abcdefghijklmnopqrstuvwxyz....."
"................................"
"................................"
"................................"
"................................";

static unsigned char rngFilter[256] =
"{dDOFByx8Jdo=C.{hFw:'p%m+]E-*}~4"
"O)YiM99y?%A)tldRIN4!fat`J|(iI+}h"
"]59P#T_Qx#h0q8w+F,$}Vo5Gq;<rw]Y~"
"k6>O~Ge,.DW9`hqhaSf#A.vrnhy`[2Ct"
"Bb6|7Mr+iJZG5.&7>?K@{D~6*Vs'H_*>"
"$Mh3R-F$Sp^.E5R-W1DnQzXC@Tf']xxt"
"o`GLO'Ui`S/v,aegU2HkE3Y6y!WZm%?k"
"aD/H=yH4vQg7dC*(Gx$vV[<vV?jw8s^d";
.
Pohon BBS