#8. |
Published: 2025-08-31 [Sun] 16:56, by |
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~" "~"; |
#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"; |