Last active
October 27, 2023 08:21
-
-
Save roughconsensusandrunningcode/53c47d8a5a8e3965173b52f62bde1bd9 to your computer and use it in GitHub Desktop.
JavaScript - Password generator based on crypto.getRandomValues()
This file contains 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
class PasswordGenerator { | |
#chunksFromString(string, chunkSize) { | |
const numChunks = Math.floor(string.length / chunkSize); | |
const chunks = new Array(numChunks); | |
for (let i=0, o=0; i < numChunks; ++i, o+=chunkSize) { | |
chunks[i] = string.substr(o, chunkSize); | |
} | |
return chunks; | |
} | |
// we use an alphabet of 73 symbols | |
// log2(73) ≈ 6.19, 64/log2(73) ≈ 10.34 | |
// so from a BigUint64 we can generate at most | |
// ten random symbols | |
#alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-_!$;@*?^|"; | |
#symbolsCount = 73n; | |
#charsPerBigUint64 = 10; | |
#generateEntropy(length) { | |
const array = new BigUint64Array(Math.ceil(length/this.#charsPerBigUint64)); | |
crypto.getRandomValues(array); | |
return array; | |
} | |
*#charsFromBigUint(biguint) { | |
for (let c=0; c<this.#charsPerBigUint64; c++) { | |
yield this.#alphabet[biguint % this.#symbolsCount]; | |
biguint /= this.#symbolsCount; | |
} | |
} | |
#stringFromBigUint(biguint) { | |
return [...this.#charsFromBigUint(biguint)].join(''); | |
} | |
generate(length, n=1) { | |
const totalLength = n*length; | |
const array = this.#generateEntropy(totalLength); | |
let password = ''; | |
for(let i=0; i<array.length && password.length<(totalLength); ++i) { | |
password += this.#stringFromBigUint(array[i]); | |
} | |
if (n === 1) { | |
return password.substr(0, length); | |
} | |
return this.#chunksFromString(password, length); | |
} | |
} | |
const gen = new PasswordGenerator(); | |
// generate 5 passwords of length 15 | |
passwords = gen.generate(15,5); | |
console.log(passwords); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment