Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Brute force the string
- * @param {Number} len
- * @param {Function} checkFunc that return Promise resolved to boolean if bruted value is matching
- * @returns {Promise} Result of brute force
- */
- const bruteString = (len, checkFunc) => {
- const startTime = Date.now();
- const symbols = [..."0123456789qwertyuiopasdfghjklzzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM!@#$%^&*()_-=+{}[]\\|?/.>,<;:'\"`~"];
- const limit = Math.pow(symbols.length, len) - 1;
- const loopLimit = 32767;
- const loopDelay = 10;
- const infoIntervalDelay = 1000;
- const wordIndexArray = [];
- for (let i = 0; i < len; i++) wordIndexArray.push(0);
- let totalIterations = 0;
- let finished = false;
- const updateIndexes = () => {
- let changingSymbol = 0;
- let shift = true;
- while (shift) {
- if (changingSymbol > wordIndexArray.length - 1) {
- finished = true;
- shift = false;
- } else if (wordIndexArray[changingSymbol] < symbols.length - 1) {
- wordIndexArray[changingSymbol]++;
- shift = false;
- } else {
- wordIndexArray[changingSymbol] = 0;
- changingSymbol++;
- }
- }
- };
- const nextWord = () => {
- totalIterations++;
- let word = "";
- for (let i = 0; i < len; i++) word += symbols[wordIndexArray[i]];
- updateIndexes();
- return word;
- };
- function* brute() {
- while (true) {
- let guess = nextWord();
- if (finished) return null;
- let match = yield checkFunc(guess);
- if (match) return guess;
- yield null;
- }
- }
- const getTimeString = (time) => {
- const seconds = Math.floor(time / 1000)
- const minutes = Math.floor(seconds / 60)
- const hours = Math.floor(minutes / 60)
- const days = Math.floor(hours / 24)
- switch (true) {
- case days >= 1:
- return `${days} days`
- case hours >= 1:
- return `${hours} hours ${minutes % 60} minutes`
- case minutes >= 1:
- return `${minutes} minutes ${seconds % 60} seconds`
- default:
- return `${seconds} seconds`
- break;
- }
- }
- // Spams info on bruteforce process
- const infoInterval = setInterval(() => {
- let doneCoef = totalIterations / limit;
- let intPrs = Math.round(doneCoef * 100);
- const durationTime = Date.now() - startTime;
- const timeLeft = Math.round(durationTime / doneCoef) - durationTime;
- console.info(`Progress: ${(intPrs * 100) / 100}% (${totalIterations} / ${limit})\nTime running: ${getTimeString(durationTime)}\nTime left: ${getTimeString(timeLeft)}`)
- }, infoIntervalDelay);
- return new Promise((resolve, reject) => {
- const generatorInstance = brute();
- const generatorRunner = (result) => {
- const nextIteration = () => {
- if (result.value !== null && typeof result.value.then === "function") {
- result.value.then((check) => {
- generatorRunner(generatorInstance.next(check));
- })
- } else {
- generatorRunner(generatorInstance.next());
- }
- };
- if (result.done) {
- clearTimeout(infoInterval);
- if (result.value !== null) {
- resolve(result.value);
- }
- else reject("No match found")
- } else {
- if (totalIterations % loopLimit === 0) {
- setTimeout(() => {
- nextIteration();
- }, loopDelay)
- } else {
- nextIteration();
- }
- }
- };
- generatorRunner(generatorInstance.next())
- });
- };
- // exemple of usage
- const correctCheck = (value) => {
- return Promise.resolve(value === "pass")
- }
- bruteString(4, correctCheck)
- .then((res) => {
- console.log("Match found:", res);
- })
- .catch((err) => {
- console.error(err);
- });
Add Comment
Please, Sign In to add comment