#include #include #include #include #define MAXITER 256 * 100 #define MHASHLEN 40 #define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MIN(x,y) ((x) < (y) ? (x) : (y)) int hash() { static char buf[MHASHLEN + 1]; char str[256]; int i, k, v; char c, *bp; size_t len; if (!fgets(str, sizeof(str), stdin)) return EXIT_FAILURE; len = strlen(str) -1; if (len <= 0) return EXIT_FAILURE; for (v = 0, i = 0; i < len; i++) v += str[i]; srand(v); for (bp = buf, i = 0; i < MHASHLEN / 2; i++) bp += sprintf(bp, "%02x", str[i % len] ^ (rand() % 256)); printf("%s\n", buf); return EXIT_SUCCESS; } int revhash(const char *hashstr) { char c, hexbuf[3] = { 0 }, *end, *buf; int i, k, v, maxlen, sum, *hash, sublen, aftersum; if (strlen(hashstr) % 2 != 0) goto invalid; /* alloc */ maxlen = strlen(hashstr) / 2; hash = calloc(maxlen, sizeof(int)); buf = malloc(strlen(hashstr)); if (!hash) return EXIT_FAILURE; /* convert hex to int array */ for (i = 0; i < maxlen; i++) { memcpy(hexbuf, hashstr + 2 * i, 2); hash[i] = strtol(hexbuf, &end, 16); if (end && *end) goto invalid; } /* bruteforce srand seed */ for (i = 0; i < MAXITER; i++) { srand(i); /* reverse chars for given sum */ for (sum = i, k = 0; k < maxlen && sum > 0; k++) { buf[k] = (char) hash[k] ^ (rand() % 256); if (buf[k] < 0) break; sum -= buf[k]; } /* repeat if too short */ if (k && sum == 0) { sublen = k; for (k = sublen; k < maxlen; k++) { buf[k] = (char) hash[k] ^ (rand() % 256); if (buf[k] < 0 || buf[k] != buf[k % sublen]) break; } } if (k < maxlen) continue; /* output first part we know */ printf("%.*s", sublen, buf); /* add rest of chars */ while (sum > 0) { c = MIN(127, sum); printf("%c", c); sum -= c; } printf("\n"); return EXIT_SUCCESS; } return EXIT_FAILURE; invalid: fprintf(stderr, "Invalid hash string!\n"); return EXIT_FAILURE; } int main(int argc, const char **argv) { if (argc < 2) { fprintf(stderr, "USAGE: revhash \n"); return EXIT_FAILURE; } if (!strcmp(argv[1], "hash")) return hash(); else return revhash(argv[1]); }