Skip to content

Instantly share code, notes, and snippets.

@claus
Last active April 12, 2021 04:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save claus/dd909c81d6057fdd1a690e8f6aa92775 to your computer and use it in GitHub Desktop.
Save claus/dd909c81d6057fdd1a690e8f6aa92775 to your computer and use it in GitHub Desktop.
/*
Make sure you have Node.JS and Outguess.app installed.
Copy this file as 'outguess.js' into an empty folder.
In that folder, run:
npm init
npm i guess-file-type tmp png-js
Change OUTGUESS_APP, WORK_DIR, SOURCE and VERBOSE below as you need them.
Add your keys to the keys array below.
Then run:
node outguess
Note: guess-file-type might yield false positives
*/
const { spawn } = require('child_process');
const fileGuesser = require('guess-file-type');
const tmp = require('tmp');
const fs = require('fs');
const OUTGUESS_APP = '/Applications/Outguess.app/Contents/outguess';
const WORK_DIR = '/Users/claus/Downloads/';
const SOURCE = WORK_DIR + 'Syphon-Signal-Registered-VIVIVICIVICIIVIII.jpg';
const VERBOSE = true;
const keys = [
'Gorham, New Hampshire',
'Zurich, Switzerland',
];
const allKeys = keys
.map(key => permutations(key))
.flat()
.filter((item, i, arr) => arr.indexOf(item) == i);
console.log(`Testing ${allKeys.length} keys...`);
outguessAll();
async function outguessAll() {
for (let i = 0; i < allKeys.length; i++) {
await outguess(allKeys[i]);
}
}
function outguess(key) {
const promise = new Promise((resolve, reject) => {
const out = tmp.fileSync();
const child = spawn(OUTGUESS_APP, ['-k', key, '-r', SOURCE, out.name]);
child.on('close', async code => {
const mime = await fileGuesser.guessByFileSignature(out.name);
if (mime != null && mime !== 'unknown') {
const ext = fileGuesser.getExtensionFromMime(mime);
const file = `${WORK_DIR}${key}.${ext}`;
fs.renameSync(out.name, file);
resolve({ key, mime, file });
return;
}
reject({ key, code });
});
});
return promise
.then(result => {
console.log(`🎉🎉 ${result.key}: ${result.file} (${result.mime})`);
return result;
})
.catch(e => {
VERBOSE && console.log(`👎 ${e.key}`);
return e;
});
}
function permutations(input) {
const rawKeys = input
.split(',')
.map(rawKey => rawKey.replace(/\s+/g, '').toLowerCase());
const keys = permutator(rawKeys).map(key => key.join(''));
return keys;
}
function permutator(inputArr) {
const result = [];
const permute = (arr, m = []) => {
if (arr.length === 0) {
result.push(m);
} else {
for (let i = 0; i < arr.length; i++) {
let curr = arr.slice();
let next = curr.splice(i, 1);
permute(curr.slice(), m.concat(next));
}
}
};
combinations(inputArr).forEach(arr => permute(arr));
return result;
}
function combinations(arr) {
var fn = function (active, rest, a) {
if (active.length === 0 && rest.length === 0) {
return;
}
if (rest.length === 0) {
a.push(active);
} else {
fn([...active, rest[0]], rest.slice(1), a);
fn(active, rest.slice(1), a);
}
return a;
};
return fn([], arr, []);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment