#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 mhash(const char *str, size_t len) { static char buf[MHASHLEN + 1]; int i, k, v; char c, *bp; if (!str || !*str) str = "."; 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 hash() { char str[256]; size_t len; if (!fgets(str, sizeof(str), stdin)) return EXIT_FAILURE; return mhash(str, strlen(str) - 1); } int revhash(const char *hashstr) { char c, hexbuf[3] = { 0 }, *end, buf[256]; int i, k, v, maxlen, sum, hash[256], sublen, aftersum; if (strlen(hashstr) % 2 != 0) goto invalid; maxlen = strlen(hashstr) / 2; /* 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; } } else { sublen = maxlen; } 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; buf[k++] = c; } printf("\n"); if (getenv("OUTPUT_HASH")) mhash(buf, k); 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]); }