Skip to content

Instantly share code, notes, and snippets.

@roughconsensusandrunningcode
Last active October 27, 2023 08:21
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 roughconsensusandrunningcode/53c47d8a5a8e3965173b52f62bde1bd9 to your computer and use it in GitHub Desktop.
Save roughconsensusandrunningcode/53c47d8a5a8e3965173b52f62bde1bd9 to your computer and use it in GitHub Desktop.
JavaScript - Password generator based on crypto.getRandomValues()
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