J'ai été inspiré par les réponses ci-dessus (en particulier par l'astuce de @e.vyushin concernant la sécurité de Math.random() ) et j'ai trouvé la solution suivante qui utilise crypto.getRandomValues() pour générer un tableau rond de valeurs UInt32 avec la longueur du mot de passe.
Ensuite, il boucle dans le tableau et divise chaque élément par 2^32 (valeur maximale d'un UInt32) pour calculer le rapport entre la valeur réelle et la valeur maximale possible. Ce rapport est ensuite mis en correspondance avec la chaîne charset pour déterminer quel caractère de la chaîne est choisi.
console.log(createPassword(16,"letters+numbers+signs"));
function createPassword(len, charset) {
if (charset==="letters+numbers") {
var chars = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
} else if (charset==="letters+numbers+signs") {
var chars = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!§$%&/?#+-_@";
}
var arr = new Uint32Array(len);
var maxRange = Math.pow(2,32);
var passwd = '';
window.crypto.getRandomValues(arr);
for (let i=0;i<len;i++) {
var c = Math.floor(arr[i] / maxRange * chars.length + 1);
passwd += chars.charAt(c);
}
return passwd;
}
Ainsi, le code est capable d'utiliser l'avantage de la crypto-Classe (sécurité améliorée pour la génération de valeurs aléatoires) et est adaptable pour utiliser tout type de jeu de caractères que l'utilisateur souhaite. L'étape suivante consisterait à utiliser des chaînes d'expressions régulières pour définir le jeu de caractères à utiliser.