98

What would be the best approach to creating a 8 character random password containing a-z, A-Z and 0-9?

Absolutely no security issues, this is merely for prototyping, I just want data that looks realistic.

I was thinking a for (0 to 7) Math.random to produce ASCII codes and convert them to characters. Do you have any other suggestions?

peirix
  • 36,512
  • 23
  • 96
  • 126
  • 1
    Nope, that seems reasonable, provided you really, really aren't using it for anything serious. – Dominic Rodger Sep 30 '09 at 11:16
  • As I said, prototyping a new website, only, and just want to create dummy values that would look realistic...I don't think my boss would be too happy if I started creating passwords with javascript on a live site :D – peirix Sep 30 '09 at 11:18
  • 1
    possible duplicate of [Generate a string of 5 random characters in JavaScript](http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript) – Sheepy Apr 17 '15 at 10:06
  • You can try [this](http://passwordgenerator.zippyout.com/) – abhaygarg12493 Apr 06 '17 at 05:21

35 Answers35

220

I would probably use something like this:

function generatePassword() {
    var length = 8,
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
        retVal = "";
    for (var i = 0, n = charset.length; i < length; ++i) {
        retVal += charset.charAt(Math.floor(Math.random() * n));
    }
    return retVal;
}

That can then be extended to have the length and charset passed by a parameter.

Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 1
    Should probably be `Math.random() * n`. Other than that, works perfectly, and as you said, is easily modifiable. Thanks (: – peirix Sep 30 '09 at 11:23
  • @peirix: You’re right, `Math.random` does only return values of 0..1. – Gumbo Sep 30 '09 at 11:27
  • 1
    PS! The `floor` isn't needed. In this case, it will make `9` unobtainable. – peirix Sep 30 '09 at 11:48
  • 1
    @peirix: No, using `Math.floor` doesn’t make any difference. – Gumbo Sep 30 '09 at 11:51
  • 2
    @faeb187 this intentionally weakens the password. Better to display the password in courier format or another font type that better distinguishes characters. – Ross Dec 07 '15 at 05:12
  • 1
    @Ross While you're right on both accounts, removing those characters is not even remotely going to impact on the real world difference between a weak / strong password. – 8eecf0d2 Mar 18 '16 at 09:34
  • @Ross Human-entry transcription of passwords makes lookalike characters problematic. A single extra minimum character requirement completely offsets the reduction of probability space for medium length passwords. Otherwise we'd be saying that base 2 radix is weaker than base 10. – LateralFractal Jun 19 '17 at 02:33
  • 2
    Here a little fiddle to generate 20 random passwords (based on the code above): https://jsfiddle.net/trehzzg9/ Just change 20 to whatever number you need and click on run. -- For "usability" you can remove the chars O, 0, I and l to prevent confusion: https://jsfiddle.net/trehzzg9/1/ – Avatar Feb 12 '18 at 15:35
  • I have no idea why this got so many votes. Should be more like: `function generatePassword(){ let charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; let n = charset.length, a = []; for(let i=0,l=8; i – StackSlave Feb 22 '21 at 23:44
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:19
67

Real Quick-n-dirty™

Math.random().toString(36).slice(2, 10)

Voilà! 8 random alphanumeric characters.

The idea is to cast a random number (in the range 0..1) to a base36 string (lowercase a-z plus 0-9), and then fetch the first 8 characters after the leading zero and decimal point.

However, please be aware that different browsers and javascript implementations used to give different bit depth results for Math.random(). If you are running in an old pre-2016 chrome or pre-2017 safari browser, this might mean (in worst case scenario) you get a shorter password than 8 characters. Though, you could solve this by simply concatenating two strings, and then slice it back down to 8 characters again.

A better solution

Though, please be aware that Math.random() was never designed or meant to be cryptographically secure. Since you only want passwords 8 characters long, I assume you're not interested in this in any case. However, for reference (and everyone else), I'll show a solution based on an actual CSPRNG. The idea is the same, we're just utilizing window.crypto instead.

window.crypto.getRandomValues(new BigUint64Array(1))[0].toString(36)

Here we are generating 1 word with 64 bits of random data, and cast it to a base36 string (0-9 and a-z). It should give you a truly random string roughly 10-13 characters long.

Extending the solution

However, to make it more secure we also want it to be longer and with mixed upper and lower cases.

We could do this either by just repeating the process twice:

let strings = window.crypto.getRandomValues(new BigUint64Array(2));
console.log(strings[0].toString(36) + strings[1].toString(36).toUpperCase());

Or we could make a fancy generic generator which uses Array.reduce to concatenate multiple random 64 bit words, alternating between uppercasing each stanza:

window.crypto.getRandomValues(new BigUint64Array(length)).reduce(
    (prev, curr, index) => (
        !index ? prev : prev.toString(36)
    ) + (
        index % 2 ? curr.toString(36).toUpperCase() : curr.toString(36)
    )
);

length is the number of 64 bit words to join. I generally use 4, which gives me rougly 48-52 random alphanumeric characters, upper and lower cased.

If you specifically want "special characters" included, you can optionally replace the 0-9 numbers in the uppercase stanzas with a simple replace() call.

const regx = new RegExp(/\d/, "g");
window.crypto.getRandomValues(new BigUint64Array(length)).reduce(
    (prev, curr, index) => (
        !index ? prev : prev.toString(36)
    ) + (
        index % 2 ? curr.toString(36).toUpperCase().replace(regx, key => ".,:;-_()=*".charAt(key)) : curr.toString(36)
    )
);

You may also optionally shuffle the final order, which is easily accomplished with this chaining "oneliner"

password.split('').sort(
    () => 128 - window.crypto.getRandomValues(new Uint8Array(1))[0]
).join('')

The idea here is to split the generated string into an array of characters, and then sort that character array with cryptographical randomness, and finally joining it back into a string.

Personally, I have this little bookmarklet saved in my browser bookmarks bar, for quick and easy access whenever I need to generate a site-specific username:

javascript:(
  function(){
    prompt('Here is your shiny new random string:', 
      window.crypto.getRandomValues(new BigUint64Array(4)).reduce(
        (prev, curr, index) => (
          !index ? prev : prev.toString(36)
        ) + (
          index % 2 ? curr.toString(36).toUpperCase() : curr.toString(36)
        )
      ).split('').sort(() => 128 -
        window.crypto.getRandomValues(new Uint8Array(1))[0]
      ).join('')
    );
  }
)();

Compatibility notices

BigUint64Array was added in:

Crypto.getRandomValues() has better support (except for Node):

  • Chrome 11
  • Edge 12
  • Firefox 21
  • Safari 5
  • Node 15.0

So if you're still on team IE 11 or use end-of-life node versions, you're stuck with using a polyfill, math.round() or a workaround with other types such as BigUInt32Array.

Xyz
  • 5,955
  • 5
  • 40
  • 58
  • I like it but it does not create uppercase letters which many password restrictions require. – Michael Warner Sep 24 '19 at 20:30
  • 3
    You could just do: `Math.random().toString(36) + Math.random().toString(36).toUpperCase()` To solve that. As an added bonus, you will get two decimal dots as well so all those requirements for a special character are solved as well. I have evolved my original answer to this: `javascript:(function(){prompt('Here is your shiny new password:',(Math.random().toString(36)+Math.random().toString(36).toUpperCase()).split('').sort(function(){return 0.5-Math.random()}).join(''));return false;})();` The only difference, apart from the toUpperCase is the `split('').sort().join('')` part. – Xyz Sep 24 '19 at 22:16
  • how can I add symbols to this? – Yu_Jain Oct 08 '22 at 21:23
  • Beware, `BigUint64Array` is only supported for about a year. You may need to polyfill. – curiouser Oct 17 '22 at 20:08
  • As @curiouser mentioned, [BigUint64Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigUint64Array), though [added to the specification in ES11 in June 2020](https://262.ecma-international.org/11.0/#table-the-typedarray-constructors) has [varying support in historic browsers](https://caniuse.com/mdn-javascript_builtins_biguint64array_biguint64array). It was added in Chrome 67 in May 2018, Node 10.4 in June 2018, Firefox 68 in July 2019, Edge 79 in January 2020 and finally Safari 15 in September 2021. So if you're still on team IE11 or Node 10.3, beware! – Xyz Jan 23 '23 at 09:15
  • @Yu_Jain, I have updated the answer with an example on how to add special characters as well. Or you could do a full search/replace for all 36 characters in the range 0-9a-z. – Xyz Jan 23 '23 at 21:31
37
function password_generator( len ) {
    var length = (len)?(len):(10);
    var string = "abcdefghijklmnopqrstuvwxyz"; //to upper 
    var numeric = '0123456789';
    var punctuation = '!@#$%^&*()_+~`|}{[]\:;?><,./-=';
    var password = "";
    var character = "";
    var crunch = true;
    while( password.length<length ) {
        entity1 = Math.ceil(string.length * Math.random()*Math.random());
        entity2 = Math.ceil(numeric.length * Math.random()*Math.random());
        entity3 = Math.ceil(punctuation.length * Math.random()*Math.random());
        hold = string.charAt( entity1 );
        hold = (password.length%2==0)?(hold.toUpperCase()):(hold);
        character += hold;
        character += numeric.charAt( entity2 );
        character += punctuation.charAt( entity3 );
        password = character;
    }
    password=password.split('').sort(function(){return 0.5-Math.random()}).join('');
    return password.substr(0,len);
}

console.log( password_generator() );

This generates a little more robust password that should pass any password strength test. eg: f1&d2?I4(h1&, C1^y1)j1@G2#, j2{h6%b5@R2)

Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
hajikelist
  • 1,136
  • 9
  • 9
  • 2
    the toUpperCase call if `(entity1 % 2 == 0)` is the same as the string would be: `AbCdEfGhIjKl...`. also the `m` is missing and the passwords length is always `len - len%3 + 3` (eg: 10 - 1 + 3 = 12) – iRaS Jul 25 '15 at 22:38
  • it's admittedly not very good, just something I used in a pinch that wasn't entirely predictable - even though you point out the modulo operation results in every other char being uppercase. – hajikelist Jul 27 '15 at 16:41
  • 1
    This creates passwords that are a little bit predictable - i.e. letter, number, symbol then letter, number, symbol, etc. See Sumit Tawal's answer for a truely random password. – Ryan Shillington Oct 13 '16 at 03:25
  • 1
    @RyanShillington I have corrected your concern. Thanks for the feedback. – Bruno Bronosky Aug 01 '18 at 20:13
  • @iRaS I just noticed and corrected your concern. Good catch. – Bruno Bronosky Aug 01 '18 at 20:21
  • I made a 4th entity for the special characters that my keyboard can easily type in. Since I did not know what your variable "hold" did, I added a boolean value that when it corresponds to uppercase basically a copy of "character +=" is ran but with ".toUpperCase()" at its end, then the boolean invert. – DynV Feb 18 '22 at 08:13
  • For anyone thinking of using this code, it is cryptographically very poor. The author has used Math.random() * Math.random() in a number of places, apparently thinking that this makes it twice as random, when in fact it makes it far less random. The numbers produced by Math.random() * Math.random() are heavily skewed towards the lower end of the range. Use a single Math.random() for a much more random output. – Graeme Falkner Sep 14 '22 at 04:41
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:17
16

This is my function for generating a 8-character crypto-random password:

function generatePassword() {
    var buf = new Uint8Array(6);
    window.crypto.getRandomValues(buf);
    return btoa(String.fromCharCode.apply(null, buf));
}

What it does: Retrieves 6 crypto-random 8-bit integers and encodes them with Base64.

Since the result is in the Base64 character set the generated password may consist of A-Z, a-z, 0-9, + and /.

holmis83
  • 15,922
  • 5
  • 82
  • 83
13
function generatePass(pLength){

    var keyListAlpha="abcdefghijklmnopqrstuvwxyz",
        keyListInt="123456789",
        keyListSpec="!@#_",
        password='';
    var len = Math.ceil(pLength/2);
    len = len - 1;
    var lenSpec = pLength-2*len;

    for (i=0;i<len;i++) {
        password+=keyListAlpha.charAt(Math.floor(Math.random()*keyListAlpha.length));
        password+=keyListInt.charAt(Math.floor(Math.random()*keyListInt.length));
    }

    for (i=0;i<lenSpec;i++)
        password+=keyListSpec.charAt(Math.floor(Math.random()*keyListSpec.length));

    password=password.split('').sort(function(){return 0.5-Math.random()}).join('');

    return password;
}
Sumit Tawal
  • 379
  • 1
  • 4
  • 9
  • Why is there only 1 special character on odd length numbers, and 2 for even ones, no matter the size? I've tried with Firefox, Edge & Chrome. – DynV Feb 17 '22 at 23:09
  • It's just to simplify the length calculation. We can tweak the logic and add flexibility to the number of special characters. – Sumit Tawal Apr 25 '22 at 16:11
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:16
9

code to generate a password with a given length (default to 8) and have at least one upper case, one lower, one number and one symbol

(2 functions and one const variable called 'Allowed')

const Allowed = {
    Uppers: "QWERTYUIOPASDFGHJKLZXCVBNM",
    Lowers: "qwertyuiopasdfghjklzxcvbnm",
    Numbers: "1234567890",
    Symbols: "!@#$%^&*"
}

const getRandomCharFromString = (str) => str.charAt(Math.floor(Math.random() * str.length))

/**
 * the generated password will be @param length, which default to 8, 
 * and will have at least one upper, one lower, one number and one symbol
 * @param {number} length - password's length
 * @returns a generated password
 */
const generatePassword = (length = 8) => {
    let pwd = "";
    pwd += getRandomCharFromString(Allowed.Uppers);  // pwd will have at least one upper
    pwd += getRandomCharFromString(Allowed.Lowers);  // pwd will have at least one lower
    pwd += getRandomCharFromString(Allowed.Numbers);  // pwd will have at least one number
    pwd += getRandomCharFromString(Allowed.Symbols); // pwd will have at least one symbol
    for (let i = pwd.length; i < length; i++)
        pwd += getRandomCharFromString(Object.values(Allowed).join(''));  // fill the rest of the pwd with random characters
    return pwd
}

Shani Kehati
  • 427
  • 5
  • 10
  • 2
    This is the most concise, elegant answer to always generate a truly strong password, should be upvoted more, thanks. – Gedeon Aug 24 '21 at 01:36
  • This SHOULD NOT be used. It Is not strong at all. Ignore the comment above. It's completely wrong. Use the window.crypto API in modern browsers. – JP_ Dec 23 '22 at 01:10
  • 1
    This code supports NodeJS, to generate a password on the backend. It's a *random* 8 (or more) characters. It's strong.. @JP_ – Shani Kehati Dec 23 '22 at 06:19
  • No, this is not strong and should never be used. Use the crypto library provided by NodeJS instead. Please read up on the topic before suggesting vulnerable solutions on SO. – JP_ Dec 24 '22 at 16:42
8

A modern and secure solution

Be aware of answers that rely on Math.random - they are not secure. This is an old question so it's no surprise that Math.random still pops up, but you should absolutely not be using it to generate a string to secure anything. If you really need to support browsers older than IE11, you should add a fallback to get the random values from the back-end, generated using a CSPRNG.

function generatePassword(length) {
  const crypto = window.crypto || window.msCrypto;

  if (typeof crypto === 'undefined') {
    throw new Error('Crypto API is not supported. Please upgrade your web browser');
  }

  const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

  const indexes = crypto.getRandomValues(new Uint32Array(length));

  let secret = '';

  for (const index of indexes) {
    secret += charset[index % charset.length];
  }

  return secret;
}

This is a simple example. You'd probably want to add special characters to the set and maybe enforce digits or symbols to be present.

Maciej Krawczyk
  • 14,825
  • 5
  • 55
  • 67
6

Here's my take (with Typescript) on this using the browser crypto API and enforcing a password which has at least:

  • 1 lower case letter
  • 1 upper case letter
  • 1 symbol
const LOWER_CASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'.split('');
const UPPER_CASE_CHARS = LOWER_CASE_CHARS.map((x) => x.toUpperCase());
const SYMBOLS = '!£$%^&*()@~:;,./?{}=-_'.split('');
const LETTERS_MIX = [...LOWER_CASE_CHARS, ...UPPER_CASE_CHARS, ...SYMBOLS];
const CHARS_LENGTH = LETTERS_MIX.length;

function containsLowerCase(str: string): boolean {
  return LOWER_CASE_CHARS.some((x) => str.includes(x));
}

function containsUpperCase(str: string): boolean {
  return UPPER_CASE_CHARS.some((x) => str.includes(x));
}

function containsSymbol(str: string): boolean {
  return SYMBOLS.some((x) => str.includes(x));
}

function isValidPassword(password: string) {
  return containsLowerCase(password) && containsUpperCase(password) && containsSymbol(password);
}

export function generateStrongPassword(length: number = 16): string {
  const buff = new Uint8Array(length);

  let generatedPassword = '';

  do {
    window.crypto.getRandomValues(buff);
    generatedPassword = [...buff].map((x) => LETTERS_MIX[x % CHARS_LENGTH]).join('');
  } while (!isValidPassword(generatedPassword));

  return generatedPassword;
}
maxime1992
  • 22,502
  • 10
  • 80
  • 121
5

If you have lodash >= 4.0 in place there is a more elegant way of doing it

var chars = 'abcdefghkmnpqrstuvwxyz23456789';
function generatePassword(length) {
  return _.sampleSize(chars, length).join('');
}
Stephan Hoyer
  • 4,792
  • 2
  • 29
  • 26
  • 2
    Note, this will only generate passwords upto 30 characters length due to the length of `chars`. For longer strings resample `chars`. – Harry Moreno Oct 17 '16 at 17:54
3

This will produce a realistic password if having characters [\]^_ is fine. Requires lodash and es7

String.fromCodePoint(...range(8).map(() => Math.floor(Math.random() * 57) + 0x41))

and here's without lodash

String.fromCodePoint(...Array.from({length: 8}, () => Math.floor(Math.random() * 57) + 65))
Harry Moreno
  • 10,231
  • 7
  • 64
  • 116
3

Here is a function provides you more options to set min of special chars, min of upper chars, min of lower chars and min of number

function randomPassword(len = 8, minUpper = 0, minLower = 0, minNumber = -1, minSpecial = -1) {
    let chars = String.fromCharCode(...Array(127).keys()).slice(33),//chars
        A2Z = String.fromCharCode(...Array(91).keys()).slice(65),//A-Z
        a2z = String.fromCharCode(...Array(123).keys()).slice(97),//a-z
        zero2nine = String.fromCharCode(...Array(58).keys()).slice(48),//0-9
        specials = chars.replace(/\w/g, '')
    if (minSpecial < 0) chars = zero2nine + A2Z + a2z
    if (minNumber < 0) chars = chars.replace(zero2nine, '')
    let minRequired = minSpecial + minUpper + minLower + minNumber
    let rs = [].concat(
        Array.from({length: minSpecial ? minSpecial : 0}, () => specials[Math.floor(Math.random() * specials.length)]),
        Array.from({length: minUpper ? minUpper : 0}, () => A2Z[Math.floor(Math.random() * A2Z.length)]),
        Array.from({length: minLower ? minLower : 0}, () => a2z[Math.floor(Math.random() * a2z.length)]),
        Array.from({length: minNumber ? minNumber : 0}, () => zero2nine[Math.floor(Math.random() * zero2nine.length)]),
        Array.from({length: Math.max(len, minRequired) - (minRequired ? minRequired : 0)}, () => chars[Math.floor(Math.random() * chars.length)]),
    )
    return rs.sort(() => Math.random() > Math.random()).join('')
}
randomPassword(12, 1, 1, -1, -1)// -> DDYxdVcvIyLgeB
randomPassword(12, 1, 1, 1, -1)// -> KYXTbKf9vpMu0
randomPassword(12, 1, 1, 1, 1)// -> hj|9)V5YKb=7
Phi Tien
  • 39
  • 3
3

I got insprired by the answers above (especially by the hint from @e.vyushin regarding the security of Math.random() ) and I came up with the following solution that uses the crypto.getRandomValues() to generate a rondom array of UInt32 values with the length of the password length.

Then, it loops through the array and devides each element by 2^32 (max value of a UInt32) to calculate the ratio between the actual value and the max. possible value. This ratio is then mapped to the charset string to determine which character of the string is picked.

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

Thus, the code is able to use the advantage of the crypto-Class (improved security for the random value generation) and is adaptable to use any kind of charset the user wished. A next step would be to use regular expression strings to define the charset to be used.

VinSta
  • 39
  • 3
2

Gumbo's solution does not work. This one does though:

function makePasswd() {
  var passwd = '';
  var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  for (i=1;i<8;i++) {
    var c = Math.floor(Math.random()*chars.length + 1);
    passwd += chars.charAt(c)
  }

  return passwd;

}
code_burgar
  • 12,025
  • 4
  • 35
  • 53
  • Gumbo's solution worked perfectly. I was able to get random characters between `a` and `9`...I'm guessing charAt will automatically `floor` or `round` the floating number. – peirix Sep 30 '09 at 11:47
  • it didn't work when copy pasted and ran, the concept is alright though – code_burgar Sep 30 '09 at 11:53
  • I'm guessing it didn't work because his first version was dividing by n, instead of multiplying it. – peirix Sep 30 '09 at 12:47
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:20
2

I see much examples on this page are using Math.random. This method hasn't cryptographically strong random values so it's unsecure. Instead Math.random recomended use getRandomValues or your own alhorytm.

You can use passfather. This is a package that are using much cryptographically strong alhorytmes. I'm owner of this package so you can ask some question.

passfather

e.vyushin
  • 79
  • 1
  • 6
  • This works well and is really nice. I'm surprised this has not existed. You should be able to make a password with one line of code. Thanks for this! – Francis Upton IV Jan 06 '21 at 16:36
  • Actually, no. This did not work when deployed with webpack. However there are other npm packages out there that do the same thing, I tried generate-password and it was fine. – Francis Upton IV Jan 06 '21 at 20:19
1

here is a simply smart code :

function generate(l) {
    if (typeof l==='undefined'){var l=8;}
    /* c : alphanumeric character string */
    var c='abcdefghijknopqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ12345679',
    n=c.length,
    /* p : special character string */
    p='!@#$+-*&_',
    o=p.length,
    r='',
    n=c.length,
    /* s : determinate the position of the special character */
    s=Math.floor(Math.random() * (p.length-1));

    for(var i=0; i<l; ++i){
        if(s == i){
            /* special charact insertion (random position s) */
            r += p.charAt(Math.floor(Math.random() * o));
        }else{
            /* alphanumeric insertion */
            r += c.charAt(Math.floor(Math.random() * n));
        }
    }
    return r;
}

Simply call generate(), and it do key containing one special character (!@#$+-*&_) for security.

Possible results : WJGUk$Ey, gaV7#fF7, ty_T55DD, YtrQMWveZqYyYKo_

There is more details and example in my website : https://www.bxnxg.com/minituto-01-generer-mots-de-passes-secures-facilements-en-javascript/

Benji_X80
  • 495
  • 1
  • 7
  • 12
1

Randomly assigns Alpha, Numeric, Caps and Special per character then validates the password. If it doesn't contain each of the above, randomly assigns a new character from the missing element to a random existing character then recursively validates until a password is formed:

function createPassword(length) {
    var alpha = "abcdefghijklmnopqrstuvwxyz";
    var caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var numeric = "0123456789";
    var special = "!$^&*-=+_?";

    var options = [alpha, caps, numeric, special];

    var password = "";
    var passwordArray = Array(length);

    for (i = 0; i < length; i++) {
        var currentOption = options[Math.floor(Math.random() * options.length)];
        var randomChar = currentOption.charAt(Math.floor(Math.random() * currentOption.length));
        password += randomChar;
        passwordArray.push(randomChar);
    }

    checkPassword();

    function checkPassword() {
        var missingValueArray = [];
        var containsAll = true;

        options.forEach(function (e, i, a) {
            var hasValue = false;
            passwordArray.forEach(function (e1, i1, a1) {
                if (e.indexOf(e1) > -1) {
                    hasValue = true;
                }
            });

            if (!hasValue) {
                missingValueArray = a;
                containsAll = false;
            }
        });

        if (!containsAll) {
            passwordArray[Math.floor(Math.random() * passwordArray.length)] = missingValueArray.charAt(Math.floor(Math.random() * missingValueArray.length));
            password = "";
            passwordArray.forEach(function (e, i, a) {
                password += e;
            });
            checkPassword();
        }
    }

    return password;
}
James
  • 305
  • 3
  • 12
1

Stop the madness!

My pain point is that every Sign-Up tool allows a different set of special characters. Some might only allow these @#$%&* while others maybe don't allow * but do allow other things. Every password generator I've come across is binary when it comes to special characters. It allows you to either include them or not. So I wind up cycling through tons of options and scanning for outliers that don't meet the requirements until I find a password that works. The longer the password the more tedious this becomes. Finally, I have noticed that sometimes Sign-Up tools don't let you repeat the same character twice in a row but password generators don't seem to account for this. It's madness!

I made this for myself so I can just paste in the exact set of special characters that are allowed. I do not pretend this is elegant code. I just threw it together to meet my needs.

Also, I couldn't think of a time when a Sign-Up tool did not allow numbers or wasn't case sensitive so my passwords always have at least one number, one upper case letter, one lower case letter, and one special character. This means the minimum length is 4. Technically I can get around the special character requirement by just entering a letter if need be.

const getPassword = (length, arg) => {
  length = document.getElementById("lengthInput").value || 16;
  arg = document.getElementById("specialInput").value || "~!@#$%^&*()_+-=[]{}|;:.,?><";
  if (length < 4) {
    updateView("passwordValue", "passwordValue", "", "P", "Length must be at least 4");
    return console.error("Length must be at least 4")
  } else if (length > 99) {
    updateView("passwordValue", "passwordValue", "", "P", "Length must be less then 100");
    return console.error("Length must be less then 100")
  }
  const lowercase = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
  const uppercase = lowercase.join("").toUpperCase().split("");
  const specialChars = arg.split("").filter(item => item.trim().length);
  const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  let hasNumber = false;
  let hasUpper = false;
  let hasLower = false;
  let hasSpecial = false;

  if (Number(length)) {
    length = Number(length)
  } else {
    return console.error("Enter a valid length for the first argument.")
  }

  let password = [];
  let lastChar;
  for (let i = 0; i < length; i++) {
    let char = newChar(lowercase, uppercase, numbers, specialChars);
    if (char !== lastChar) {
      password.push(char);
      lastChar = char
      if (Number(char)) {
        hasNumber = true
      }
      if (lowercase.indexOf(char) > -1) {
        hasLower = true
      }
      if (uppercase.indexOf(char) > -1) {
        hasUpper = true
      }
      if (specialChars.indexOf(char) > -1) {
        hasSpecial = true
      }
    } else {
      i--
    }
    if (i === length - 1 && (!hasNumber || !hasUpper || !hasLower || !hasSpecial)) {
      hasNumber = false;
      hasUpper = false;
      hasLower = false;
      hasSpecial = false;
      password = [];
      i = -1;
    }
  }

  function newChar(lower, upper, nums, specials) {
    let set = [lower, upper, nums, specials];
    let pick = set[Math.floor(Math.random() * set.length)];
    return pick[Math.floor(Math.random() * pick.length)]
  }
  updateView("passwordValue", "passwordValue", "", "P", password.join(""));
  updateView("copyPassword", "copyPassword", "", "button", "copy text");
  document.getElementById("copyPassword").addEventListener("click", copyPassword);
}

const copyPassword = () => {
  let text = document.getElementById("passwordValue").textContent;
  navigator.clipboard.writeText(text);
};

const updateView = (targetId, newId, label, element, method = '') => {
  let newElement = document.createElement(element);
  newElement.id = newId;
  let content = document.createTextNode(label + method);
  newElement.appendChild(content);

  let currentElement = document.getElementById(targetId);
  let parentElement = currentElement.parentNode;
  parentElement.replaceChild(newElement, currentElement);
}

document.getElementById("getPassword").addEventListener("click", getPassword);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
</head>

<body>
  <div>
    <button id="getPassword">Generate Password</button>
    <input type="number" id="lengthInput" placeholder="Length">
    <input type="text" id="specialInput" placeholder="Special Characters">
    <p id="passwordValue"></p>
    <p id="copyPassword"></p>
  </div>

</body>

</html>
James9446
  • 19
  • 2
1

Generate a random password of length 8 to 32 characters with at least 1 lower case, 1 upper case, 1 number, 1 special char (!@$&)

function getRandomUpperCase() {
   return String.fromCharCode( Math.floor( Math.random() * 26 ) + 65 );
}

function getRandomLowerCase() {
   return String.fromCharCode( Math.floor( Math.random() * 26 ) + 97 );
} 

function getRandomNumber() {
   return String.fromCharCode( Math.floor( Math.random() * 10 ) + 48 );
}

function getRandomSymbol() {
    // const symbol = '!@#$%^&*(){}[]=<>/,.|~?';
    const symbol = '!@$&';
    return symbol[ Math.floor( Math.random() * symbol.length ) ];
}

const randomFunc = [ getRandomUpperCase, getRandomLowerCase, getRandomNumber, getRandomSymbol ];

function getRandomFunc() {
    return randomFunc[Math.floor( Math.random() * Object.keys(randomFunc).length)];
}

function generatePassword() {
    let password = '';
    const passwordLength = Math.random() * (32 - 8) + 8;
    for( let i = 1; i <= passwordLength; i++ ) {
        password += getRandomFunc()();
    }
    //check with regex
    const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,32}$/
    if( !password.match(regex) ) {
        password = generatePassword();
    }
    return password;
}

console.log( generatePassword() );
  • This is much more complex than the approach used in the accepted answer. It even involves a regular expression. And you really do not want those, if it can be avoided. – Striezel Feb 23 '21 at 00:23
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:14
1

Answers so far are overly complicated or use Math.random() or depend on another package.

I feel the world needs yet another password generator :-)

/**
 * @param {number} length
 * @returns {string}
 */
function generateRandomPassword(length) {
    const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    return window.crypto.getRandomValues(new Uint8Array(length)).reduce((password, number) => {
        return password + charset.charAt(number % charset.length);
    }, "");
}

Valid characters are fixed but can be trivially tailored. Probability of having a digit can be increased by repeating the sequence in the charset (i.e: charset = "…vwxyz01234567890123456789").

It uses the secure getRandomValues().

It doesn't ensure the password contains at least one uppercase letter, one lowercase letter and one digit. Therefore, it might generate a real word/noun or even an offensive word. It is very unlikely with longer passwords, though. Skewing toward digits (as explained above) may not solve that issue due to l33t. Adding some special characters is the safest course if that is your concern.

PS: Should charset be more than 256 characters long, the code must use Uint16Array instead.

PPS: What's wrong with Math.random(): it is pseudo-random. The sequence is somewhat predictable. Not every possible theoretical password can be generated because the next character is determined from a computed sequence.

0

even shorter:

Array.apply(null, Array(8)).map(function() { 
    var c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    return c.charAt(Math.random() * c.length);
}).join('');

or as function:

function generatePassword(length, charSet) {
    charSet = charSet ? charSet : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789^°!"§$%&/()=?`*+~\'#,;.:-_';
    return Array.apply(null, Array(length || 10)).map(function() { 
        return charSet.charAt(Math.random() * charSet.length);
    }).join(''); 
}
iRaS
  • 1,958
  • 1
  • 16
  • 29
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:20
  • There is no reason to use math.random and judging by the misconceptions in this thread - people are thinking these are strong and potentially using them in production. So I think it's important to move the secure solutions to the top. – JP_ Dec 24 '22 at 16:50
0

Here's another approach based off Stephan Hoyer's solution

var _ = require('lodash');

function getRandomString(length) {
  var chars = 'abcdefghkmnpqrstuvwxyz23456789';
  return _.times(length, () => sample(chars)).join('');
}
Harry Moreno
  • 10,231
  • 7
  • 64
  • 116
0
function genPass(n)    // e.g. pass(10) return 'unQ0S2j9FY'
{
    let c='abcdefghijklmnopqrstuvwxyz'; c+=c.toUpperCase()+1234567890;

    return [...Array(n)].map(b=>c[~~(Math.random()*62)]).join('')
} 

Where n is number of output password characters; 62 is c.length and where e.g. ~~4.5 = 4 is trick for replace Math.floor

Alternative

function genPass(n)     // e.g. pass(10) return 'unQ0S2j9FY'
{
    let c='abcdefghijklmnopqrstuvwxyz'; c+=c.toUpperCase()+1234567890;

    return '-'.repeat(n).replace(/./g,b=>c[~~(Math.random()*62)])
} 

to extend characters list, add them to c e.g. to add 10 characters !$^&*-=+_? write c+=c.toUpperCase()+1234567890+'!$^&*-=+_?' and change Math.random()*62 to Math.random()*72 (add 10 to 62).

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:17
  • @JP_ the OP says in his question - quote: _"Absolutely no security issues, this is merely for prototyping"_. However if you need something more secure use [this](https://stackoverflow.com/a/55349874/860099) instead Math.random – Kamil Kiełczewski Dec 23 '22 at 16:50
  • That's fair! Still worth noting as there are so many misconceptions in this thread though. What do you think? – JP_ Dec 24 '22 at 16:45
0

This method gives the options to change size and charset of your password.

function generatePassword(length=8, charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
    return new Array(length)
      .fill(null)
      .map(()=> charset.charAt(Math.floor(Math.random() * charset.length)))
      .join('');
}

console.log(generatePassword()); // 02kdFjzX
console.log(generatePassword(4)); // o8L5
console.log(generatePassword(16)); // jpPd7S09txv9b02p
console.log(generatePassword(16, "abcd1234")); // 4c4d323a31c134dd
Michael Warner
  • 3,879
  • 3
  • 21
  • 45
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:16
  • Please explain. The only thing I am assuming you are referring to is how computers can't create truly random numbers. If that was a requirement for this I would go with something like calling the random.org api. https://www.random.org/clients/http/api/ – Michael Warner Jan 03 '23 at 18:06
  • Use window.crypto library. Big diff between a PRNG and a CSPRNG. Look up the details. – JP_ Jan 04 '23 at 00:24
0

A simple lodash solution that warranties 14 alpha, 3 numeric and 3 special characters, not repeated:

const generateStrongPassword = (alpha = 14, numbers = 3, special = 3) => {
  const alphaChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const numberChars = '0123456789';
  const specialChars = '!"£$%^&*()-=+_?';
  const pickedChars = _.sampleSize(alphaChars, alpha)
    .concat(_.sampleSize(numberChars, numbers))
    .concat(_.sampleSize(specialChars, special));
  return _.shuffle(pickedChars).join('');
}

const myPassword = generateStrongPassword();
Santiago Bendavid
  • 961
  • 1
  • 9
  • 16
0

I also developed my own password generator, with random length (between 16 and 40 by default), strong passwords, maybe it could help.

function randomChar(string) {
  return string[Math.floor(Math.random() * string.length)];
}

// you should use another random function, like the lodash's one.
function random(min = 0, max = 1) {
 return Math.floor(Math.random() * (max - min + 1)) + min;
}

// you could use any shuffle function, the lodash's one, or the following https://stackoverflow.com/a/6274381/6708504
function shuffle(a) {
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }

  return a;
}

function generatePassword() {
  const symbols = '§±!@#$%^&*()-_=+[]{}\\|?/<>~';
  const numbers = '0123456789';
  const lowercaseLetters = 'abcdefghijklmnopqrstuvwxyz';
  const uppercaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const minCharsGroup = 4;
  const maxCharsGroup = 10;
  const randomSymbols = [...Array(random(minCharsGroup, maxCharsGroup))].map(() => randomChar(symbols));
  const randomNumbers = [...Array(random(minCharsGroup, maxCharsGroup))].map(() => randomChar(numbers));
  const randomUppercasesLetters = [...Array(random(minCharsGroup, maxCharsGroup))].map(() => randomChar(uppercaseLetters));
  const randomLowercasesLetters = [...Array(random(minCharsGroup, maxCharsGroup))].map(() => randomChar(lowercaseLetters));
  const chars = [...randomSymbols, ...randomNumbers, ...randomUppercasesLetters, ...randomLowercasesLetters];

  return shuffle(chars).join('');
}
MadDeveloper
  • 1,000
  • 8
  • 13
0
const alpha = 'abcdefghijklmnopqrstuvwxyz';
const calpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const num = '1234567890';
const specials = ',.!@#$%^&*';
const options = [alpha, alpha, alpha, calpha, calpha, num, num, specials];
let opt, choose;
let pass = "";
for ( let i = 0; i < 8; i++ ) {
  opt = Math.floor(Math.random() * options.length);
  choose = Math.floor(Math.random() * (options[opt].length));
  pass = pass + options[opt][choose];
  options.splice(opt, 1);
}
console.log(pass);

Length 8 characters

At least 1 Capital

At least 1 Number

At least 1 Special Character

Vinit Khandelwal
  • 490
  • 8
  • 20
0

Update: replacing the core Math.random() by crypto.getRandomValues and add options

Solution with scrambling:

const Allowed = {
  Uppers: 'QWERTYUIOPASDFGHJKLZXCVBNM',
  Lowers: 'qwertyuiopasdfghjklzxcvbnm',
  Numbers: '1234567890',
  Symbols: '!@#$%^&*'
}
const AllowedUpperArray = Array.from(Allowed.Uppers)
const AllowedLowerArray = Array.from(Allowed.Lowers)
const AllowedNumberArray = Array.from(Allowed.Numbers)
const AllowedSymbolArray = Array.from(Allowed.Symbols)

function getCharAt(charArray, index) {
  return charArray[index % charArray.length]
}

function scrambleArray(chars) {
  return chars.sort(() => Math.random() - 0.5)
}

function getAllowedChars(compositionRule = {}) {
  let chars = []
  if (!compositionRule.upperCase?.forbidden) chars = chars.concat(AllowedUpperArray)
  if (!compositionRule.lowerCase?.forbidden) chars = chars.concat(AllowedLowerArray)
  if (!compositionRule.numbers?.forbidden) chars = chars.concat(AllowedNumberArray)
  if (!compositionRule.symbols?.forbidden) chars = chars.concat(AllowedSymbolArray)
  return chars
}

function assertAreRulesValid(compositionRule) {
  const {
    upperCase,
    lowerCase,
    numbers,
    symbols
  } = compositionRule

  if (length < 1) throw new Error('length < 1')
  if (upperCase?.min < 0) throw new Error('upperCase.min < 0')
  if (lowerCase?.min < 0) throw new Error('lowerCase.min < 0')
  if (numbers?.min < 0) throw new Error('numbers.min < 0')
  if (symbols?.min < 0) throw new Error('symbols.min < 0')
  if (length && length < (upperCase?.min || 0 + lowerCase?.min || 0 + numbers?.min || 0 + symbols?.min || 0)) throw new Error('length < sum of min')
  if (upperCase?.forbidden && lowerCase?.forbidden && numbers?.forbidden && symbols?.forbidden) throw new Error('no char type allowed')
  if (upperCase?.forbidden && upperCase?.min) throw new Error('forbidden incompatible with min')
  if (lowerCase?.forbidden && lowerCase?.min) throw new Error('forbidden incompatible with min')
  if (symbols?.forbidden && symbols?.min) throw new Error('forbidden incompatible with min')
  if (numbers?.forbidden && numbers?.min) throw new Error('forbidden incompatible with min')
}

/**
 * Generates password of the given length with at least one upper, one lower, one number and one symbol.
 * @param length length of the password, min 4
 * @throws Error if length is less than 4
 */
function generatePassword(length = 8, compositionRule = {}) {
  const {
    upperCase,
    lowerCase,
    numbers,
    symbols
  } = compositionRule

  const indexes = crypto.getRandomValues(new Uint32Array(length));

  const chars = []
  let i = 0
  let lastIndex = i
  while (i < upperCase?.min || 0) chars.push(getCharAt(AllowedUpperArray, indexes[i++]))
  while (i < lastIndex + lowerCase?.min || 0) chars.push(getCharAt(AllowedLowerArray, indexes[i++]))
  lastIndex = i
  while (i < lastIndex + numbers?.min || 0) chars.push(getCharAt(AllowedNumberArray, indexes[i++]))
  lastIndex = i
  while (i < lastIndex + symbols?.min || 0) chars.push(getCharAt(AllowedSymbolArray, indexes[i++]))
  
  const allowedChars = getAllowedChars(compositionRule)

  while (i < length || 0) chars.push(getCharAt(allowedChars, indexes[i++]))

  return scrambleArray(chars).join('')
}

const opt1 = {
  upperCase: { min: 3 },
  lowerCase: { forbidden: true },
  numbers: { min: 2 },
  symbols: { min: 1 }
}
const pwd1 = generatePassword(10, opt1)

console.log('10 characters, min 3 uppercase, 2 numbers, 1 symbol and no lowercase:', pwd1)

const opt2 = {
  upperCase: { forbidden: true },
  lowerCase: { forbidden: true },
  numbers: { forbidden: true },
  symbols: { min: 1 }
}
const pwd2 = generatePassword(5, opt2)

console.log('5 characters, min 1 symbol but upperCase, lowercase, and numbers forbidden:', pwd2)
Pleymor
  • 2,611
  • 1
  • 32
  • 44
0

ascii character set, you could also use node.js node:crypto random function for a more crypto secure random.

const password = (length) => () => {
        let pass="";
        for(let l=0; l < length; l++) {
        const rand = Math.random() * (126 - 33) + 33;
                pass += String.fromCharCode(~~rand);
    }
    return pass;
}
const createpass = password(32);
console.log(createpass());
console.log(createpass());
Shadow Angel
  • 71
  • 1
  • 2
-1

Here's a free, configurable Javascript class generating random passwords: Javascript Random Password Generator.

Examples

Password consisting of Lower case + upper case + numbers, 8 characters long:

var randomPassword = new RandomPassword();
document.write(randomPassword.create());

Password consisting of Lower case + upper case + numbers, 20 characters long:

var randomPassword = new RandomPassword();
document.write(randomPassword.create(20));

Password consisting of Lower case + upper case + numbers + symbols, 20 characters long:

var randomPassword = new RandomPassword();
document.write(randomPassword.create(20,randomPassword.chrLower+randomPassword.chrUpper+randomPassword.chrNumbers+randomPassword.chrSymbols));  
Per Kristian
  • 785
  • 8
  • 10
-1
var createPassword = function() {
  var passAt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  var passArray = Array.from({length: 15})

  return passArray.map(function(_, index) { 
    return index % 4 == 3 ? '-' : passAt.charAt(Math.random() * passAt.length)
  }).join('')
}

result like:

L5X-La0-bN0-UQO
9eW-svG-OdS-8Xf
ick-u73-2s0-TMX
5ri-PRP-MNO-Z1j
mycoin
  • 9
  • 2
-1

Here's a quick dynamic modern solution which I thought I'll share

const generatePassword = (
  passwordLength = 8,
  useUpperCase = true,
  useNumbers = true,
  useSpecialChars = true,
) => {
  const chars = 'abcdefghijklmnopqrstuvwxyz'
  const numberChars = '0123456789'
  const specialChars = '!"£$%^&*()'

  const usableChars = chars
   + (useUpperCase ? chars.toUpperCase() : '')
   + (useNumbers ? numberChars : '')
   + (useSpecialChars ? specialChars : '')

  let generatedPassword = ''

  for(i = 0; i <= passwordLength; i++) {
    generatedPassword += usableChars[Math.floor(Math.random() * (usableChars.length))]
  }

  return generatedPassword
}
Shay
  • 2,060
  • 2
  • 16
  • 22
-1
const length = 18; // you can use length as option or static
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
const numbers = '0123456789';
const symbols = '!#$%&\()*+,-./:;<=>?@^[\\]^_`{|}~';

let password = '';

let validChars = '';

// all if conditions can be used to custom password
if (useLetters) {
    validChars += letters;
}

if (useNumbers) {
    validChars += numbers;
}

if (useSymbols) {
    validChars += symbols;
}

let generatedPassword = '';

for (let i = 0; i < length; i++) {
    const index = Math.floor(Math.random() * validChars.length);
    generatedPassword += validChars[index];
}

password = generatedPassword;
sasha romanov
  • 485
  • 1
  • 10
  • 26
-1

It's not very hard. You just have to learn about its concepts. You need to learn:

  1. Functions
  2. Variables
  3. Working with strings
  4. Mathematics
  5. loops
  6. DOM (if you're working with HTML) and the code is:
function gen(){
  // Save all the possible characters in a variable
  var chars = "abcdef";
  // make an empty variable to store random characters.
  var pw = "";
  // we need loop.
  // repeat four times then we have password with 4 characters
  for (var i=0; i<4; i++){
    // select random character
    var rand = Math.round(Math.random() * chars.length);
    // insert that random character to pw variable
    var pw += chars.charAt(rand);
  }
  // then return pw
  // Use console.log() || DOM || "return pw"
  return pw;
}
Front Cutted
  • 9
  • 1
  • 3
-1

My version for Node.js:

import { randomInt } from "crypto";

export const secret = (length = 64) => {
  const upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const lowerCase = "abcdefghijklmnopqrstuvwxyz";
  const digits = "0123456789";
  const minus = "-";
  const underLine = "_";
  const special = "!\"#$%&'*+,./:;=?@\\^`|~";
  const brackets = "[]{}()<>";
  const alphabet =
    upperCase + lowerCase + digits + minus + underLine + special + brackets;
  let secret = "";
  for (let index = 0; index < length; index++)
    secret += alphabet.charAt(randomInt(alphabet.length));
  return secret;
};

Source: https://github.com/Parsifal/secret

Parsifal
  • 42
  • 3
-2

Short Oneliner:

var pass=(a=>Array.from({length:11},_=>a[~~(Math.random()*a.length)]).join(''))('*$§!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
console.log(pass);
Dieter Bender
  • 37
  • 1
  • 2
  • Code only answers are discouraged on SO. Good answers include an explanation, & are more likely to be upvoted. Consider editing to add an explanaton, or links to documentation. Also, try splitting this up onto multiple "lines" (it can still be a "one-liner" solution if you want, just add whitespace/lines so the entire solution fits in the SO window) so it is readable without scrolling. Scrolling means it's less likely to be read, thus less likely to be useful or upvoted. Also when scrolling, you cannot see the entire line of code at once, so there is a tiny bit of unnecessary cognitive load. – SherylHohman Jan 17 '22 at 17:30
  • sorry, but you can not split this up into multiple lines! The script works why downvoting? – Dieter Bender Feb 01 '22 at 17:05
  • Not secure due to use of Math.random(). – JP_ Dec 23 '22 at 01:13