Last active
July 27, 2021 18:22
-
-
Save azanli/d76796a79b39d446f4a90c1610709751 to your computer and use it in GitHub Desktop.
Scramble an ordered list of digits hashed by a secret passphrase
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Scramble Ordered Digits | |
| * | |
| * This function takes in a `passphrase` and `limit` argument and returns | |
| * a scrambled list of digits, n ... {limit}. | |
| * | |
| * This assumes that the original ordered digits are whole numbers starting | |
| * from 1 ... {limit} where `limit` is the max digit. | |
| * | |
| * For example, `scrambleOrderedDigits('Hello World')` hashes 24 digits to the order on the right-hand side: | |
| * | |
| * 1 13 >> 9 13 | |
| * 2 14 >> 24 2 | |
| * 3 15 >> 6 14 | |
| * 4 16 >> 18 3 | |
| * 5 17 >> 1 15 | |
| * 6 18 >> 22 4 | |
| * 7 19 >> 5 16 | |
| * 8 20 >> 17 11 | |
| * 9 21 >> 8 12 | |
| * 10 22 >> 20 21 | |
| * 11 23 >> 10 7 | |
| * 12 24 >> 23 19 | |
| */ | |
| const scrambleOrderedDigits = (passphrase, limit = 24) => { | |
| if (typeof passphrase !== 'string') { | |
| throw new Error('Passphrase must be a string.'); | |
| } else if (passphrase.length < 4) { | |
| throw new Error('Passphrase must contain a minimum of four units.'); | |
| } | |
| let key = passphrase + passphrase.split('').reverse().join(''); | |
| const map = {}; | |
| const result = []; | |
| const scrambledResult = []; | |
| const hashes = key.split('').map((char, idx) => { | |
| let code = char.charCodeAt(); | |
| if (map[code]) { | |
| while (map[code]) { | |
| code += key.length; | |
| } | |
| } | |
| map[code] = true; | |
| return code; | |
| }); | |
| let seq = 0; | |
| let nxt = 0; | |
| while (scrambledResult.length < limit) { | |
| let hash = Math.floor(hashes[seq] / 2) ** Math.floor(hashes[nxt] / 2); | |
| while (map[hash] && isNaN(hash)) { | |
| hash = Math.floor(hashes[seq] / 2) ** Math.floor(hashes[nxt++] / 2); | |
| } | |
| if (!isNaN(hash) && scrambledResult.indexOf(hash) === -1) { | |
| map[hash] = true; | |
| scrambledResult.push(hash); | |
| } | |
| if (seq + nxt > hashes.length - 2) { | |
| seq += 1; | |
| nxt = seq; | |
| } else { | |
| nxt += 1; | |
| } | |
| } | |
| const sortedResult = [...scrambledResult].sort((a, b) => a - b); | |
| for (let i = 0; i < limit; i += 1) { | |
| result.push(scrambledResult.indexOf(sortedResult[i]) + 1); | |
| } | |
| return result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment