#1. tripex tripcode finding software |
Published: 2025-01-05 [Sun] 00:04, by |
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"; |