Generate random password string with requirements in javascript

前端 未结 20 1514
夕颜
夕颜 2020-12-07 07:56

I want to generate a random string that has to have 5 letters from a-z and 3 numbers.

How can I do this with JavaScript?

I\'ve got the following script, but

相关标签:
20条回答
  • 2020-12-07 08:16

    Well, you can always use window.crypto object available in the recent version of browser.

    Just need one line of code to get a random number:

    let n = window.crypto.getRandomValues(new Uint32Array(1))[0];
    

    It also helps to encrypt and decrypt data. More information at MDN Web docs - window.crypto.

    0 讨论(0)
  • 2020-12-07 08:21

    A little more maintainable and secure approach.

    An update to expand on what I meant and how it works.

    1. Secure. MDN is pretty explicit about the use of Math.random for anything related to security:

      Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.

      Looking at the can-i-use for getRandomValues in 2020 you probably don't need the msCrypto and Math.random fallback any more, unless you care about ancient browsers.

    2. Maintainable is mostly about the RegExp _pattern as an easy way to define what character classes you allow in the password. But also about the 3 things where each does its job: defines a pattern, gets a random byte as securely as possible, provides a public API to combine the two.

    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)'>

    0 讨论(0)
  • 2020-12-07 08:22

    My Crypto based take on the problem. Using ES6 and omitting any browser feature checks. Any comments on security or performance?

    const generatePassword = (
      passwordLength = 12,
      passwordChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
    ) =>
      [...window.crypto.getRandomValues(new Uint32Array(passwordLength))]
        .map(x => passwordChars[x % passwordChars.length])
        .join('');
    
    0 讨论(0)
  • 2020-12-07 08:24

    In case you need a password generated with at least 1 number, 1 upper case character, and 1 lower case character:

    function generatePassword(passwordLength) {
      var numberChars = "0123456789";
      var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      var lowerChars = "abcdefghijklmnopqrstuvwxyz";
      var allChars = numberChars + upperChars + lowerChars;
      var randPasswordArray = Array(passwordLength);
      randPasswordArray[0] = numberChars;
      randPasswordArray[1] = upperChars;
      randPasswordArray[2] = lowerChars;
      randPasswordArray = randPasswordArray.fill(allChars, 3);
      return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
    }
    
    function shuffleArray(array) {
      for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
      }
      return array;
    }
    
    alert(generatePassword(12));
    

    Here's the fiddle if you want to play/test: http://jsfiddle.net/sJGW4/155/

    Props to @mwag for giving me the start to create this.

    0 讨论(0)
  • 2020-12-07 08:25

    Many answers (including the original of this one) don't address the letter- and number-count requirements of the OP. Below are two solutions: general (no min letters/numbers), and with rules.

    General:

    I believe this is better general solution than the above, because:

    • it's more secure than accepted/highest-voted answer, and also more versatile, because it supports any char set in a case-sensitive manner
    • it's more concise than other answers (for general solution, 3 lines max; can be one-liner)
    • it uses only native Javascript- no installation or other libs required

    Note that

    • for this to work on IE, the Array.fill() prototype must be polyfilled
    • if available, better to use window.crypto.getRandomValues() instead of Math.random() (thanks @BenjaminH for pointing out)

    Three-liner:

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

    Or, as one-liner:

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

    With Letter / Number Rules

    Now, a variation on the above. This will generate three random strings from the given charsets (letter, number, either) and then scramble the result.

    Please note the below uses sort() for illustrative purposes only. For production use, replace the below sort() function with a shuffle function such as Durstenfeld.

    First, as a function:

    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);
    

    Same thing, as a 2-liner (admittedly, very long and ugly lines-- and won't be a 1-liner if you use a proper shuffle function. Not recommended but sometimes it's fun anyway) :

    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 讨论(0)
  • 2020-12-07 08:25

    There is a random password string generator with selected length

    let input = document.querySelector("textarea");
    let button = document.querySelector("button");
    let length = document.querySelector("input");
    
    function generatePassword(n) 
    {
    	let pwd = "";
    
      while(!pwd || pwd.length < n)
      {
      	pwd += Math.random().toString(36).slice(-22);
      }
      
      return pwd.substring(0, n);
    }
    
    button.addEventListener("click", function()
    {
    	input.value = generatePassword(length.value);
    });
    <div>password:</div>
    <div><textarea cols="70" rows="10"></textarea></div>
    <div>length:</div>
    <div><input type="number" value="200"></div>
    <br>
    <button>gen</button>

    0 讨论(0)
提交回复
热议问题