Generate random password string with requirements in javascript

前端 未结 20 1513
夕颜
夕颜 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:06

    Try this, it works. Download script to your javascript application and call function randomPassword() https://gist.github.com/enishant/4ba920c71f338e83c7089dc5d6f33a64

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

    Any password generated with Math.random() is EXTREMELY BAD.

    This function uses the system time as a seed for the random number generator. Anyone who knows the time the password was generated can easily brute-force the password.

    In almost all cases, this data is easily available - just take the registration_time column in a hacked database, and test out all the values generated by the Math.random() algorithm using the times from 15 to 0 minutes before.

    A password generated with Math.random() is completely worthless because the time the password was first used is enough for cracking it.

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

    For someone who is looking for a simplest script. No while (true), no if/else, no declaration.

    Base on mwag's answer, but this one uses crypto.getRandomValues, a stronger random than Math.random.

    Array(20)
      .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
      .map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)])
      .join('');
    

    See this for 0xffffffff.

    Alternative 1

    var generatePassword = (
      length = 20,
      wishlist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
    ) => Array(length)
          .fill('')
          .map(() => wishlist[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * wishlist.length)])
          .join('');
    
    console.log(generatePassword());
    

    Alternative 2

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

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

    This isn't exactly optimized, but it should work.

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

    ​ ​ ​

    Here's a jsfiddle for you to test on: http://jsfiddle.net/sJGW4/3/

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

    As @RobW notes, restricting the password to a fixed number of characters as proposed in the OP scheme is a bad idea. But worse, answers that propose code based on Math.random are, well, a really bad idea.

    Let's start with the bad idea. The OP code is randomly selecting a string of 8 characters from a set of 62. Restricting the random string to 5 letters and 3 numbers means the resulting passwords will have, at best, 28.5 bits of entropy (as opposed to a potential of 47.6 bits if the distribution restriction of 5 letters and 3 numbers were removed). That's not very good. But in reality, the situation is even worse. The at best aspect of the code is destroyed by the use of Math.random as the means of generating entropy for the passwords. Math.random is a pseudo random number generator. Due to the deterministic nature of pseudo random number generators the entropy of the resulting passwords is really bad , rendering any such proposed solution a really bad idea. Assuming these passwords are being doled out to end users (o/w what's the point), an active adversary that receives such a password has very good chance of predicting future passwords doled out to other users, and that's probably not a good thing.

    But back to the just bad idea. Assume a cryptographically strong pseudo random number generator is used instead of Math.random. Why would you restrict the passwords to 28.5 bits? As noted, that's not very good. Presumably the 5 letters, 3 numbers scheme is to assist users in managing randomly doled out passwords. But let's face it, you have to balance ease of use against value of use, and 28.5 bits of entropy isn't much value in defense against an active adversary.

    But enough of the bad. Let's propose a path forward. I'll use the JavaScript EntropyString library which "efficiently generates cryptographically strong random strings of specified entropy from various character sets". Rather than the OP 62 characters, I'll use a character set with 32 characters chosen to reduce the use of easily confused characters or the formation of English words. And rather than the 5 letter, 3 number scheme (which has too little entropy), I'll proclaim the password will have 60 bits of entropy (this is the balance of ease versus value).

    import { Entropy, charSet32 } from 'entropy-string'
    const random = new Entropy({ bits: 60, charset: charset32 })
    const string = random.string()
    

    "Q7LfR8Jn7RDp"

    Note the arguments to Entropy specify the desired bits of entropy as opposed to more commonly seen solutions to random string generation that specify passing in a string length (which is both misguided and typically underspecified, but that's another story).

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

    I have written a small one inspired from your answer:

    (function(){g=function(){c='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';p='';for(i=0;i<8;i++){p+=c.charAt(Math.floor(Math.random()*62));}return p;};p=g();while(!/[A-Z]/.test(p)||!/[0-9]/.test(p)||!/[a-z]/.test(p)){p=g();}return p;})()
    

    This function returns the password and can be used in bookmarklet like:

    javascript:alert(TheCodeOfTheFunction);
    
    0 讨论(0)
提交回复
热议问题