116 votes

Générer une chaîne de mots de passe aléatoire avec des exigences en javascript

Je veux générer une chaîne aléatoire qui doit comporter 5 lettres de a à z et 3 chiffres.

Comment puis-je faire cela avec JavaScript ?

J'ai le script suivant, mais il ne répond pas à mes exigences.

        var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        var string_length = 8;
        var randomstring = '';
        for (var i=0; i<string_length; i++) {
            var rnum = Math.floor(Math.random() * chars.length);
            randomstring += chars.substring(rnum,rnum+1);
        }

7 votes

S'il répond à votre exigence, quelle est la question alors ? En outre, votre exigence de mot de passe forcé est une mauvaise idée.

8 votes

4 votes

new Array(12).fill().map(() => String.fromCharCode(Math.random()*86+40)).join("") Une solution astucieuse pour produire un mot de passe de 12 caractères avec des caractères spéciaux, des chiffres supérieurs et inférieurs, dans une approche très légère.

350voto

Rob W Points 125904

Imposer un nombre fixe de caractères est une mauvais idée. Ça n'améliore pas la qualité du mot de passe. Pire, elle réduit le nombre de mots de passe possibles, de sorte que le piratage par forçage brutal devient plus facile.

Pour générer un mot aléatoire composé de caractères alphanumériques, utilisez :

var randomstring = Math.random().toString(36).slice(-8);

Comment cela fonctionne-t-il ?

Math.random()                        // Generate random number, eg: 0.123456
             .toString(36)           // Convert  to base-36 : "0.4fzyo82mvyr"
                          .slice(-8);// Cut off last 8 characters : "yo82mvyr"

Documentation pour le Number.prototype.toString et string.prototype.slice méthodes.

7 votes

Je suis d'accord, mais parfois on n'a pas le droit de décider ;)

0 votes

Pourriez-vous expliquer ce qui se passe dans votre réponse ? C'est un bon truc !

0 votes

@zessx Quel navigateur utilisez-vous ? Dans FF32, je viens de vérifier 10.000.000 et j'ai obtenu seulement 18 doublons. Pour vos chiffres, c'est pratiquement 0.

50voto

saaj Points 412

Une approche un peu plus facile à maintenir et plus sûre.

Une mise à jour pour développer ce que je voulais dire et comment cela fonctionne.

  1. Secure . MDN est assez explicite sur l'utilisation de Math.random pour tout ce qui concerne la sécurité :

    Math.random() n'est pas fournissent des nombres aléatoires cryptographiquement sécurisés. Ne les utilisez pas pour tout ce qui concerne la sécurité. Utilisez plutôt l'API Crypto Web, et plus précisément l'API window.crypto.getRandomValues() méthode.

    Regarder la can-i-utilisation pour getRandomValues en 2020, vous n'avez probablement pas besoin de la msCrypto et Math.random à moins que vous ne vous préoccupiez des anciens navigateurs.

  2. Maintenable concerne surtout le RegExp _pattern comme un moyen facile de définir les classes de caractères que vous autorisez dans le mot de passe. Mais aussi sur les 3 points où chacun fait son travail : définir un modèle, obtenir un octet aléatoire de manière aussi sûre que possible, fournir une API publique pour combiner les deux.

    var Password = {

    pattern : /[a-zA-Z0-9-+.]/,

    _getRandomByte : function() { // http://caniuse.com/#feat=getrandomvalues if(window.crypto && window.crypto.getRandomValues) { var result = new Uint8Array(1); window.crypto.getRandomValues(result); return result[0]; } else if(window.msCrypto && window.msCrypto.getRandomValues) { var result = new Uint8Array(1); window.msCrypto.getRandomValues(result); return result[0]; } else { return Math.floor(Math.random() * 256); } },

    generate : function(length) { return Array.apply(null, {'length': length}) .map(function() { var result; while(true) { result = String.fromCharCode(this._getRandomByte()); if(this._pattern.test(result)) { return result; } }
    }, this) .join('');
    }

    };

    <input type='text' id='p'/><br/> <input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>

1 votes

De plus, cela n'ajoute pas toujours un chiffre au code généré et le PO veut un minimum de 3.

0 votes

J'ai trouvé une bibliothèque qui prend en charge window.crypto.getRandomValues et qui fonctionne également avec node.js. github.com/bermi/password-generator

0 votes

Je voulais juste dire que j'avais besoin de quelque chose pour générer des mots de passe en un rien de temps et c'était parfait. Merci !

36voto

mwag Points 1

De nombreuses réponses (y compris l'original de celle-ci) ne répondent pas aux exigences de l'OP en matière de nombre de lettres et de chiffres. Voici deux solutions : générale (pas de lettres/chiffres minimums), et avec des règles.

Général :

Je pense que cette solution générale est meilleure que la précédente, car.. :

  • c'est plus sûr que la réponse acceptée/la plus votée, et aussi plus polyvalent, car il prend en charge n'importe quel jeu de caractères en respectant la casse
  • elle est plus concise que les autres réponses (pour une solution générale, 3 lignes maximum ; peut être une seule ligne)
  • il n'utilise que le Javascript natif - aucune installation ou autre librairie n'est requise.

Notez que

  • pour que cela fonctionne sur IE, le prototype Array.fill() doit être polyfilled
  • si disponible, il vaut mieux utiliser window.crypto.getRandomValues() au lieu de Math.random() (merci à @BenjaminH de l'avoir signalé)

Une ligne de trois :

var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var pwdLen = 10;
var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

Ou, en guise de remarque :

var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

Avec des règles pour les lettres et les chiffres

Maintenant, une variation sur ce qui précède. Cela va générer trois chaînes aléatoires à partir des jeux de caractères donnés (lettre, chiffre, soit) et ensuite brouiller le résultat.

Veuillez noter que l'exemple ci-dessous utilise sort() à des fins d'illustration uniquement. Pour une utilisation en production, remplacez la fonction sort() ci-dessous par une fonction remue-ménage fonction telle que Durstenfeld .

D'abord, en tant que fonction :

function randPassword(letters, numbers, either) {
  var chars = [
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", // letters
   "0123456789", // numbers
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" // either
  ];

  return [letters, numbers, either].map(function(len, i) {
    return Array(len).fill(chars[i]).map(function(x) {
      return x[Math.floor(Math.random() * x.length)];
    }).join('');
  }).concat().join('').split('').sort(function(){
    return 0.5-Math.random();
  }).join('')
}

// invoke like so: randPassword(5,3,2);

Même chose, en tant que 2-liner (certes, des lignes très longues et laides - et qui ne seront pas une 1-liner si vous utilisez une fonction shuffle appropriée. Ce n'est pas recommandé, mais c'est parfois amusant) :

var chars = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz","0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"];
var randPwd = [5,3,2].map(function(len, i) { return Array(len).fill(chars[i]).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('') }).concat().join('').split('').sort(function(){return 0.5-Math.random()}).join('');

0 votes

Bonne réponse, mais la lettre majuscule Y n'apparaîtra jamais dans un mot de passe que vous générez.

1 votes

Merci. J'ai utilisé le jeu de caractères dans la question de l'OP mais il semble qu'il était défectueux. Mis à jour maintenant.

0 votes

Vous dites "c'est plus sûr que la réponse acceptée/la plus votée". Pouvez-vous préciser la raison ?

26voto

Reegan Points 131

Pour quelqu'un qui cherche un script le plus simple possible. Non while (true) non if/else pas de déclaration.

Sur la base de mwag's réponse mais celui-ci utilise crypto.getRandomValues un hasard plus fort que Math.random .

var generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.getRandomValues(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

Bookmarklet

javascript:prompt("Random password:",((o=20,n="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$")=>Array.from(crypto.getRandomValues(new Uint32Array(o))).map(o=>n[o%n.length]).join(""))())

Node.js

const crypto = require('crypto')

const generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.randomFillSync(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

Python

#!/usr/bin/env python

import os

def rand(length: int) -> str:
    bytes = os.urandom(length)
    chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-"
    cl = len(chars)
    rs = ''
    for i in bytes:
        rs += chars[i % cl]
    return rs

print(rand(18))

1 votes

Cela ne donne pas systématiquement des mots de passe de longueur 20, à cause d'un décalage non défini. Le site + 1 n'est pas nécessaire et peut être supprimée.

0 votes

Bonne prise @bryc. Mis à jour. Merci.

1 votes

Une solution utile et facile. Quiconque cherche à faire cela dans NodeJS peut simplement remplacer crypto.getRandomValues avec crypto.randomFillSync .

8voto

Alec Sanger Points 1848

Ce n'est pas exactement optimisé, mais cela devrait fonctionner.

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 8;
var randomstring = '';
var charCount = 0;
var numCount = 0;

for (var i=0; i<string_length; i++) {
    // If random bit is 0, there are less than 3 digits already saved, and there are not already 5 characters saved, generate a numeric value. 
    if((Math.floor(Math.random() * 2) == 0) && numCount < 3 || charCount >= 5) {
        var rnum = Math.floor(Math.random() * 10);
        randomstring += rnum;
        numCount += 1;
    } else {
        // If any of the above criteria fail, go ahead and generate an alpha character from the chars string
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
        charCount += 1;
    }
}

alert(randomstring);

Voici une jsfiddle pour que vous puissiez la tester : http://jsfiddle.net/sJGW4/3/

1 votes

chars.substring(rnum, rnum+1) c'est comme chars.charAt(rnum)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X