Generate random string/characters in JavaScript

Viewed 2377443

I want a 5 character string composed of characters picked randomly from the set [a-zA-Z0-9].

What's the best way to do this with JavaScript?

91 Answers

Here's an improvement on doubletap's excellent answer. The original has two drawbacks which are addressed here:

First, as others have mentioned, it has a small probability of producing short strings or even an empty string (if the random number is 0), which may break your application. Here is a solution:

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

Second, both the original and the solution above limit the string size N to 16 characters. The following will return a string of size N for any N (but note that using N > 16 will not increase the randomness or decrease the probability of collisions):

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

Explanation:

  1. Pick a random number in the range [0,1), i.e. between 0 (inclusive) and 1 (exclusive).
  2. Convert the number to a base-36 string, i.e. using characters 0-9 and a-z.
  3. Pad with zeros (solves the first issue).
  4. Slice off the leading '0.' prefix and extra padding zeros.
  5. Repeat the string enough times to have at least N characters in it (by Joining empty strings with the shorter random string used as the delimiter).
  6. Slice exactly N characters from the string.

Further thoughts:

  • This solution does not use uppercase letters, but in almost all cases (no pun intended) it does not matter.
  • The maximum string length at N = 16 in the original answer is measured in Chrome. In Firefox it's N = 11. But as explained, the second solution is about supporting any requested string length, not about adding randomness, so it doesn't make much of a difference.
  • All returned strings have an equal probability of being returned, at least as far as the results returned by Math.random() are evenly distributed (this is not cryptographic-strength randomness, in any case).
  • Not all possible strings of size N may be returned. In the second solution this is obvious (since the smaller string is simply being duplicated), but also in the original answer this is true since in the conversion to base-36 the last few bits may not be part of the original random bits. Specifically, if you look at the result of Math.random().toString(36), you'll notice the last character is not evenly distributed. Again, in almost all cases it does not matter, but we slice the final string from the beginning rather than the end of the random string so that short strings (e.g. N=1) aren't affected.

Update:

Here are a couple other functional-style one-liners I came up with. They differ from the solution above in that:

  • They use an explicit arbitrary alphabet (more generic, and suitable to the original question which asked for both uppercase and lowercase letters).
  • All strings of length N have an equal probability of being returned (i.e. strings contain no repetitions).
  • They are based on a map function, rather than the toString(36) trick, which makes them more straightforward and easy to understand.

So, say your alphabet of choice is

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Then these two are equivalent to each other, so you can pick whichever is more intuitive to you:

Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

and

Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

Edit:

I seems like qubyte and Martijn de Milliano came up with solutions similar to the latter (kudos!), which I somehow missed. Since they don't look as short at a glance, I'll leave it here anyway in case someone really wants a one-liner :-)

Also, replaced 'new Array' with 'Array' in all solutions to shave off a few more bytes.

A newer version with es6 spread operator:

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')

  • The 30 is an arbitrary number, you can pick any token length you want
  • The 36 is the maximum radix number you can pass to numeric.toString(), which means all numbers and a-z lowercase letters
  • The 2 is used to pick the 3rd index from the random string which looks like this: "0.mfbiohx64i", we could take any index after 0.

To meet requirement [a-zA-Z0-9] and length=5 use

For Browser:

btoa(Math.random().toString()).substr(10, 5);

For NodeJS:

Buffer.from(Math.random().toString()).toString("base64").substr(10, 5);

Lowercase letters, uppercase letters, and numbers will occur.

(it's typescript compatible)

Generate a secure random alphanumeric Base-62 string:

function generateUID(length)
{
    return window.btoa(String.fromCharCode(...window.crypto.getRandomValues(new Uint8Array(length * 2)))).replace(/[+/]/g, "").substring(0, length);
}

console.log(generateUID(22)); // "yFg3Upv2cE9cKOXd7hHwWp"
console.log(generateUID(5)); // "YQGzP"

There is no best way to do this. You can do it any way you prefer, as long as the result suits your requirements. To illustrate, I've created many different examples, all which should provide the same end-result

Most other answers on this page ignore the upper-case character requirement.

Here is my fastest solution and most readable. It basically does the same as the accepted solution, except it is a bit faster.

function readableRandomStringMaker(length) {
  for (var s=''; s.length < length; s += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.charAt(Math.random()*62|0));
  return s;
}
console.log(readableRandomStringMaker(length));
// e3cbN

Here is a compact, recursive version which is much less readable:

const compactRandomStringMaker = (length) => length-- && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) + (compactRandomStringMaker(length)||"");
console.log(compactRandomStringMaker(5));
// DVudj

A more compact one-liner:

Array(5).fill().map(()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62)).join("")
// 12oEZ

A variation of the above:

"     ".replaceAll(" ",()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62))

The most compact one-liner, but inefficient and unreadable - it adds random characters and removes illegal characters until length is l:

((l,f=(p='')=>p.length<l?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())(5)

A cryptographically secure version, which is wasting entropy for compactness, and is a waste regardless because the generated string is so short:

[...crypto.getRandomValues(new Uint8Array(999))].map((c)=>String.fromCharCode(c).replace(/[^a-z0-9]/i,'')).join("").substr(0,5)
// 8fzPq

Or, without the length-argument it is even shorter:

((f=(p='')=>p.length<5?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())()
// EV6c9

Then a bit more challenging - using a nameless recursive arrow function:

((l,s=((l)=>l--&&"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0)+(s(l)||""))) => s(l))(5);
// qzal4

This is a "magic" variable which provides a random character every time you access it:

const c = new class { [Symbol.toPrimitive]() { return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) } };
console.log(c+c+c+c+c);
// AgMnz

A simpler variant of the above:

const c=()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0);
c()+c()+c()+c()+c();
// 6Qadw
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

Improved @Andrew's answer above :

Array.from({ length : 1 }, () => Math.random().toString(36)[2]).join('');

Base 36 conversion of the random number is inconsistent, so selecting a single indice fixes that. You can change the length for a string with the exact length desired.

One liner:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

Case Insensitive Alphanumeric Chars:

function randStr(len) {
  let s = '';
  while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
  return s;
}

// usage
console.log(randStr(50));

The benefit of this function is that you can get different length random string and it ensures the length of the string.

Case Sensitive All Chars:

function randStr(len) {
  let s = '';
  while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
  return s;
}

// usage
console.log(randStr(50));

Custom Chars

function randStr(len, chars='abc123') {
  let s = '';
  while (len--) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

// usage
console.log(randStr(50));
console.log(randStr(50, 'abc'));
console.log(randStr(50, 'aab')); // more a than b

Crypto-Strong

If you want to get crypto-strong string which meets your requirements (I see answer which use this but gives non valid answers) use

let pass = n=> [...crypto.getRandomValues(new Uint8Array(n))]
   .map((x,i)=>(i=x/255*61|0,String.fromCharCode(i+(i>9?i>35?61:55:48)))).join``

let pass = n=> [...crypto.getRandomValues(new Uint8Array(n))]
   .map((x,i)=>(i=x/255*61|0,String.fromCharCode(i+(i>9?i>35?61:55:48)))).join``

console.log(pass(5));

Update: thanks to Zibri comment I update code to get arbitrary-long password

I did not find a clean solution for supporting both lowercase and uppercase characters.

Lowercase only support:

Math.random().toString(36).substr(2, 5)

Building on that solution to support lowercase and uppercase:

Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

Change the 5 in substr(2, 5) to adjust to the length you need.

Here is my approach (with TypeScript).

I've decided to write yet another response because I didn't see any simple solution using modern js and clean code.

const DEFAULT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

function getRandomCharFromAlphabet(alphabet: string): string {
  return alphabet.charAt(Math.floor(Math.random() * alphabet.length));
}

function generateId(idDesiredLength: number, alphabet = DEFAULT_ALPHABET): string {
  /**
   * Create n-long array and map it to random chars from given alphabet.
   * Then join individual chars as string
   */
  return Array.from({length: idDesiredLength}).map(() => {
    return getRandomCharFromAlphabet(alphabet);
  }).join('');
}

generateId(5); // jNVv7

One-liner using map that gives you full control on the length and characters.

const rnd = (len, chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') => [...Array(len)].map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join('')

console.log(rnd(12))

Just a simple map or reduce implementation should suffice:

const charset: string =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

const random1: string = [...Array(5)]
  .map((_) => charset[Math.floor(Math.random() * charset.length)])
  .join("");

const random2: string = [...Array(5)]
  .reduce<string>(
    (acc) => acc += charset[Math.floor(Math.random() * charset.length)],
    "",
  );

How about something like this: Date.now().toString(36) Not very random, but short and quite unique every time you call it.

This one combines many of the answers give.

var randNo = Math.floor(Math.random() * 100) + 2 + "" + new Date().getTime() +  Math.floor(Math.random() * 100) + 2 + (Math.random().toString(36).replace(/[^a-zA-Z]+/g, '').substr(0, 5));

console.log(randNo);

I have been using it for 1 month with great results.

If you just want uppercase letters (A-Z):

randomAZ(n: number): string {
      return Array(n)
        .fill(null)
        .map(() => Math.random()*100%25 + 'A'.charCodeAt(0))
        .map(a => String.fromCharCode(a))
        .join('')
 }

If you just want the first letter to be uppercase (A-Z), and the rest to be lower case (a-z):

function RandomWord(n: number): string {
    return Array(n)
      .fill(null)
      .map(() => Math.random()*100%25 + 'A'.charCodeAt(0))
      .map((a, i) => i === 0? String.fromCharCode(a) : String.fromCharCode(a+32))
      .join('')
}

One liner [a-z]:

String.fromCharCode(97 + Math.floor(Math.random() * 26))

If you are developing on node js, it is better to use crypto. Here is an example of implementing the randomStr() function

const crypto = require('crypto');
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(crypto.randomInt(charset.length)))
    .join('');

If you are not working in a server environment, just replace the random number generator:

const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(Math.floor(Math.random() * charset.length)))
    .join('');

For a string with upper- and lowercase letters and digits (0-9a-zA-Z), this may be the version that minifies best:

function makeId(length) {
  var id = '';
  var rdm62;
  while (length--) {
   // Generate random integer between 0 and 61, 0|x works for Math.floor(x) in this case 
   rdm62 = 0 | Math.random() * 62; 
   // Map to ascii codes: 0-9 to 48-57 (0-9), 10-35 to 65-90 (A-Z), 36-61 to 97-122 (a-z)
   id += String.fromCharCode(rdm62 + (rdm62 < 10 ? 48 : rdm62 < 36 ? 55 : 61)) 
  }
  return id;
}

The content of this function minifies to 97 bytes, while the top answer needs 149 bytes (because of the characters list).

This is a slightly improved version of doubletap's answer. It considers gertas's comment about the case, when Math.random() returns 0, 0.5, 0.25, 0.125, etc.

((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)
  1. It prevents that zero gets passed to toString my adding the smallest float to Math.random().
  2. It ensures that the number passed to toString has enough digits by dividing through an almost irrational number.

How about this below... this will produce the really random values:

function getRandomStrings(length) {
  const value = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const randoms = [];
  for(let i=0; i < length; i++) {
     randoms.push(value[Math.floor(Math.random()*value.length)]);
  }
  return randoms.join('');
}

But if you looking for a shorter syntax one in ES6:

const getRandomStrings = length => Math.random().toString(36).substr(-length);

Generate any number of hexadecimal character (e.g. 32):

(function(max){let r='';for(let i=0;i<max/13;i++)r+=(Math.random()+1).toString(16).substring(2);return r.substring(0,max).toUpperCase()})(32);

Posting an ES6-compatible version for posterity. If this is called a lot, be sure to store the .length values into constant variables.

// USAGE:
//      RandomString(5);
//      RandomString(5, 'all');
//      RandomString(5, 'characters', '0123456789');
const RandomString = (length, style = 'frictionless', characters = '') => {
    const Styles = {
        'all':          allCharacters,
        'frictionless': frictionless,
        'characters':   provided
    }

    let result              = '';
    const allCharacters     = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const frictionless      = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    const provided          = characters;

    const generate = (set) => {
        return set.charAt(Math.floor(Math.random() * set.length));
    };

    for ( let i = 0; i < length; i++ ) {
        switch(Styles[style]) {
            case Styles.all:
                result += generate(allCharacters);
                break;
            case Styles.frictionless:
                result += generate(frictionless);
                break;
            case Styles.characters:
                result += generate(provided);
                break;
        }
    }
    return result;
}

export default RandomString;

Teach a man to fish:

Programmers cut paper with lasers, not chainsaws. Using fringe, language specific methods to produce the smallest, most obfuscated code is cute and all, but will never offer a complete solution. You have to use the right tool for the job.

What you want is a string of characters, and characters are represented by bytes. And, we can represent a byte in JavaScript using a number. So then, we should generate a list of these numbers, and cast them as strings. You don't need Date, or base64; Math.random() will get you a number, and String.fromCharCode() will turn it into a string. Easy.

But, which number equals which character? UTF-8 is the primary standard used on the web to interpret bytes as characters (although JavaScript uses UTF-16 internally, they overlap). The programmer's way of solving this problem is to look into the documentation.

UTF-8 lists all the keys on the keyboard in the numbers between 0 and 128. Some are non-printing. Simply pick out the characters you want in your random strings, and search for them, using randomly generated numbers.

Bellow is a function that takes a virtually infinite length, generates a random number in a loop, and searches for all the printing characters in the lower 128 UTF-8 codes. Entropy is inherent, since not all random numbers will hit every time (non-printing characters, white space, etc). It will also perform faster as you add more characters.

I've included most of the optimizations discussed in the thread:

  • The double tilde is faster than Math.floor
  • "if" statements are faster than regular expressions
  • pushing to an array is faster than string concatenation

function randomID(len) {
  var char;
  var arr = [];
  var len = len || 5;

  do {
    char = ~~(Math.random() * 128);

    if ((
        (char > 47 && char < 58) || // 0-9
        (char > 64 && char < 91) || // A-Z
        (char > 96 && char < 123) // a-z

        // || (char > 32 && char < 48) // !"#$%&,()*+'-./
        // || (char > 59 && char < 65) // <=>?@
        // || (char > 90 && char < 97) // [\]^_`
        // || (char > 123 && char < 127) // {|}~
      )
      //security conscious removals: " ' \ ` 
      //&& (char != 34 && char != 39 && char != 92 && char != 96) 

    ) { arr.push(String.fromCharCode(char)) }

  } while (arr.length < len);

  return arr.join('')
}

var input = document.getElementById('length');

input.onfocus = function() { input.value = ''; }

document.getElementById('button').onclick = function() {
  var view = document.getElementById('string');
  var is_number = str => ! Number.isNaN( parseInt(str));
    
  if ( is_number(input.value))
    view.innerText = randomID(input.value);
  else
    view.innerText = 'Enter a number';
}
#length {
  width: 3em;
  color: #484848;
}

#string {
  color: #E83838;
  font-family: 'sans-serif';
  word-wrap: break-word;
}
<input id="length" type="text" value='#'/>
<input id="button" type="button" value="Generate" />
<p id="string"></p>

Why do it in this tedious way? Because you can. You're a programmer. You can make a computer do anything! Besides, what if you want a string of Hebrew characters? It's not hard. Find those characters in the UTF-8 standard and search for them. Free yourself from these McDonald methods like toString(36).

Sometimes, dropping down to a lower level of abstraction is what's needed to create a real solution. Understanding the fundamental principals at hand can allow you to customize your code how you'd like. Maybe you want an infinitely generated string to fill a circular buffer? Maybe you want all of your generated strings to be palindromes? Why hold yourself back?

I have made a String prototype which can generate a random String with a given length.

You also can secify if you want special chars and you can avoid some.

/**
 * STRING PROTOTYPE RANDOM GENERATOR
 * Used to generate a random string
 * @param {Boolean} specialChars
 * @param {Number} length
 * @param {String} avoidChars
 */
String.prototype.randomGenerator = function (specialChars = false, length = 1, avoidChars = '') {
    let _pattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    _pattern += specialChars === true ? '(){}[]+-*/=' : '';
    if (avoidChars && avoidChars.length) {
        for (let char of avoidChars) {
            _pattern = _pattern.replace(char, '');
        }
    }
    let _random = '';
    for (let element of new Array(parseInt(length))) {
        _random += _pattern.charAt(Math.floor(Math.random() * _pattern.length));
    }
    return _random;
};

You can use like this :

// Generate password with specialChars which contains 10 chars and avoid iIlL chars
var password = String().randomGenerator(true, 10, 'iIlL');

Hope it helps.

Random unicode string

This method will return a random string with any of the supported unicode characters, which is not 100% what OP asks for, but what I was looking for:

function randomUnicodeString(length){
    return Array.from({length: length}, ()=>{
        return String.fromCharCode(Math.floor(Math.random() * (65536)))
    }).join('')
}

Rationale

This is the top result of google when searching for "random string javascript", but OP asks for a-zA-Z0-9 only.

As several people here have pointed out, passing the result of Math.random() directly to .string(36) has several problems.

It has poor randomness. The number of characters generated varies, and on average depends on the tricky details of how floating-point numbers work in Javascript. It seems to work if I am trying to generate 11 characters or fewer, but not with more than 11. And it is not flexible. There is no easy way to allow or prohibit certain characters.

I have a compact solution, which doesn't have these problems, for anyone using lodash:

_.range(11).map(i => _.sample("abcdefghijklmnopqrstuvwxyz0123456789")).join('')

If you want to allow certain characters (such as uppercase letters) or prohibit certain characters (like ambiguous characters such as l and 1), modify the string above.

I just write a simple package to generate a random token with given size, seed and mask. FYI.

@sibevin/random-token - https://www.npmjs.com/package/@sibevin/random-token

import { RandomToken } from '@sibevin/random-token'

RandomToken.gen({ length: 32 })
// JxpwdIA37LlHan4otl55PZYyyZrEdsQT

RandomToken.gen({ length: 32, seed: 'alphabet' })
// NbbtqjmHWJGdibjoesgomGHulEJKnwcI

RandomToken.gen({ length: 32, seed: 'number' })
// 33541506785847193366752025692500

RandomToken.gen({ length: 32, seed: 'oct' })
// 76032641643460774414624667410327

RandomToken.gen({ length: 32, seed: 'hex' })
// 07dc6320bf1c03811df7339dbf2c82c3

RandomToken.gen({ length: 32, seed: 'abc' })
// bcabcbbcaaabcccabaabcacbcbbabbac

RandomToken.gen({ length: 32, mask: '123abcABC' })
// vhZp88dKzRZGxfQHqfx7DOL8jKTkWUuO

How about extending the String object like so.

String.prototype.random = function(length) {
   var result = '';
   for (var i = 0; i < length; i++) {
      result += this.charAt(Math.floor(Math.random() * this.length));
   }

   return result;
};

using it:

console.log("ABCDEFG".random(5));
function generate(length) {
  var letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"];
  var IDtext = "";
  var i = 0;
  while (i < length) {
    var letterIndex = Math.floor(Math.random() * letters.length);
    var letter = letters[letterIndex];
    IDtext = IDtext + letter;
    i++;
  }
  console.log(IDtext)
}
[..."abcdefghijklmnopqrsuvwxyz0123456789"].map((e, i, a) => a[Math.floor(Math.random() * a.length)]).join('')

Generate random strings with aA-zZ and 0-9 charachters collection. Just call this function with length parameter.

So to answer to this question: generateRandomString(5)

generateRandomString(length){
    let result = "", seeds

    for(let i = 0; i < length - 1; i++){
        //Generate seeds array, that will be the bag from where randomly select generated char
        seeds = [
            Math.floor(Math.random() * 10) + 48,
            Math.floor(Math.random() * 25) + 65,
            Math.floor(Math.random() * 25) + 97
        ]
        
        //Choise randomly from seeds, convert to char and append to result
        result += String.fromCharCode(seeds[Math.floor(Math.random() * 3)])
    }

    return result
}

Version that generates strings without numbers:

generateRandomString(length){
    let result = "", seeds

    for(let i = 0; i < length - 1; i++){
        seeds = [
            Math.floor(Math.random() * 25) + 65,
            Math.floor(Math.random() * 25) + 97
        ]
        result += String.fromCharCode(seeds[Math.floor(Math.random() * 2)])
    }

    return result
}

recursive solution:

function generateRamdomId (seedStr) {
const len = seedStr.length
console.log('possibleStr', seedStr , ' len ', len)
if(len <= 1){
    return seedStr
}
const randomValidIndex  = Math.floor(Math.random() * len)
const randomChar = seedStr[randomValidIndex]
const chunk1 = seedStr.slice(0, randomValidIndex)
const chunk2 = seedStr.slice(randomValidIndex +1)
const possibleStrWithoutRandomChar = chunk1.concat(chunk2)

return randomChar + generateRamdomId(possibleStrWithoutRandomChar)

}

you can use with the seed you want , dont repeat chars if you dont rea. Example

generateRandomId("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") 

Simple method:

function randomString(length) {
    let chars = [], output = '';
    for (let i = 32; i < 127; i ++) {
        chars.push(String.fromCharCode(i));
    }
    for (let i = 0; i < length; i ++) {
        output += chars[Math.floor(Math.random() * chars.length )];
    }
    return output;
}

If you want more or less characters change the "127" to something else.

Review

Many answers base on trick Math.random().toString(36) but the problem of this approach is that Math.random not always produce number which has at least 5 characters in base 36 e.g.

let testRnd = n => console.log(`num dec: ${n}, num base36: ${n.toString(36)}, string: ${n.toString(36).substr(2, 5)}`);


[
  Math.random(),
  // and much more less than 0.5...
  0.5,
  0.50077160493827161,
  0.5015432098765432,
  0.5023148148148148,
  0.5030864197530864,
  // and much more....
  0.9799597050754459
].map(n=>testRnd(n));

console.log('... and so on');
Each of below example (except first) numbers result with less than 5 characters (which not meet OP question requirements)

Here is "generator" which allows manually find such numbers

function base36Todec(hex) {
  hex = hex.split(/\./);
  return (parseInt(hex[1],36))*(36**-hex[1].length)+ +(parseInt(hex[0],36));
}

function calc(hex) {
  let dec = base36Todec(hex);
  msg.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${dec.toString(36)}</b>`
} 

function calc2(dec) {
  msg2.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${(+dec).toString(36)}</b>`
} 

let init="0.za1";
inp.value=init;
calc(init);
Type number in range 0-1 using base 36 (0-9,a-z) with less than 5 digits after dot<br>
<input oninput="calc(this.value)" id="inp" /><div id="msg"></div>
<br>
If above <i>hex test</i> give more digits than 5 after dot - then you can try to copy dec number to below field and join some digit to dec num right side and/or change last digit - it sometimes also produce hex with less digits<br>
<input oninput="calc2(this.value)" /><br><div id="msg2"></div>

I already give answer here so I will not put here another solution

The following code will produce a cryptographically secured random string of size containing [a-zA-Z0-9], using an npm package crypto-random-string. Install it using:

npm install crypto-random-string

To get a random string of 30 characters in the set [a-zA-Z0-9]:

const cryptoRandomString = require('crypto-random-string');
cryptoRandomString({length: 100, type: 'base64'}).replace(/[/+=]/g,'').substr(-30);

Summary: We are replacing /, +, = in a large random base64 string and getting the last N characters.

PS: Use -N in substr

In case you cannot type out a charset, using String.fromCharCode and a ranged Math.random allows you to create random strings in any Unicode codepoint range. For example, if you want 17 random Tibetan characters, you can input ranstr(17,0xf00,0xfff), where (0xf00,0xfff) corresponds to the Tibetan Unicode block. In my implementation, the generator will spit out ASCII text if you do not specify a codepoint range.

    function ranchar(a,b) {
       a = (a === undefined ? 0 : a);
       b = (b === undefined ? 127 : b);
       return String.fromCharCode(Math.floor(Math.random() * (b - a) + a)); 
    }
    
    function ranstr(len,a,b) {
      a = a || 32;
      var result = '';
      for(var i = 0; i < len; i++) {
       result += ranchar(a,b)
      }
      return result;
    }


//Here are some examples from random Unicode blocks
console.log('In Latin Basic block: '+ ranstr(10,0x0000,0x007f))
console.log('In Latin-1 Supplement block: '+ ranstr(10,0x0080,0x0ff))
console.log('In Currency Symbols block: ' + ranstr(10,0x20a0,0x20cf))
console.log('In Letterlike Symbols block: ' + ranstr(10,0x2100,0x214f))
console.log('In Dingbats block:' + ranstr(10,0x2700,0x27bf))

Love this SO question and their answers. So cleaver and creative solutions were proposed. I came up with mine that is wrapped inside a function that receives the length of the string you want to obtain plus a mode argument to decide how you want it to be composed.

Mode is a 3 length string that accepts only '1s' and '0s' that define what subsets of characters you want to include in the final string. It is grouped by 3 different subset( [0-9], [A-B], [a-b])

'100': [0-9]
'010': [A-B]
'101': [0-9] + [a-b]
'111': [0-9] + [A-B] + [a-b]

There are 8 possible combinations (2^N, witn N:#subsets). The '000' mode return an empty string.

function randomStr(l = 1, mode = '111') {
    if (mode === '000') return '';
    const r = (n) => Math.floor(Math.random() * n);
    const m = [...mode].map((v, i) => parseInt(v, 10) * (i + 1)).filter(Boolean).map((v) => v - 1);
    return [...new Array(l)].reduce((a) => a + String.fromCharCode([(48 + r(10)), (65 + r(26)), (97 + r(26))][m[r(m.length)]]), '')
}

A simple use case will be:

random = randomStr(50, '101')
// ii3deu9i4jk6dp4gx43g3059vss9uf7w239jl4itv0cth5tj3e
// Will give you a String[50] composed of [0-9] && [a-b] chars only.

The main idea here is to use the UNICODE table instead of randomizing hexadecimals as I saw in many answers. THe power of this approach is that you can extend it very easily to include others subsets of the UNICODE table with litte extra code in there that a random int(16) can't do.

You can use Web Crypto's API:

console.log(self.crypto.getRandomValues(new Uint32Array(1))[0])

(original answer here)

Above All answers are perfect. but I am adding which is very good and rapid to generate any random string value

function randomStringGenerator(stringLength) {
  var randomString = ""; // Empty value of the selective variable
  const allCharacters = "'`~!@#$%^&*()_+-={}[]:;\'<>?,./|\\ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'"; // listing of all alpha-numeric letters
  while (stringLength--) {
    randomString += allCharacters.substr(Math.floor((Math.random() * allCharacters.length) + 1), 1); // selecting any value from allCharacters varible by using Math.random()
  }
  return randomString; // returns the generated alpha-numeric string
}

console.log(randomStringGenerator(10));//call function by entering the random string you want

or

console.log(Date.now())// it will produce random thirteen numeric character value every time.
console.log(Date.now().toString().length)// print length of the generated string

//creates a random code which is 10 in lenght,you can change it to yours at your will

function createRandomCode(length) {
    let randomCodes = '';
    let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let charactersLength = characters.length;
    for (let i = 0; i < length; i++ ) {
        randomCodes += characters.charAt(Math.floor(Math.random() * charactersLength))
    }
    console.log("your reference code is: ".toLocaleUpperCase() + randomCodes);
 };
 createRandomCode(10)

This is not a perfect solution, but it should work. If you ever get any error, then increase the value given in Uint8Array() constructor. The advantage of this method is it uses getRandomValues() method that generates cryptographically strong random values.

var array = new Uint8Array(20);
crypto.getRandomValues(array);
var arrayEncoded =  btoa(String.fromCharCode(...array)).split('');
var arrayFiltered = arrayEncoded.filter(value => {
    switch (value){
    case "+" :
        return false;
    case "/" :
        return false;
    case "=" :
        return false;
    default :
      return true;
   }
});
var password = arrayFiltered.slice(0,5).join('');
console.log(password);

A compact Version

var array = new Uint8Array(20);
crypto.getRandomValues(array);
var password = btoa(String.fromCharCode(...array)).split('').filter(value => {
        return !['+', '/' ,'='].includes(value);
}).slice(0,5).join('');
console.log(password);

To generate a hash from an array as a salt, [0,1,2,3] in this example, by this way we may be able to retrieve the hash later to populate a condition.

Simply feed a random array, or use as extra safe and fast finger-printing of arrays.

/* This method is very fast and is suitable into intensive loops */
/* Return a mix of uppercase and lowercase chars */

/* This will always output the same hash, since the salt array is the same */
console.log(
  btoa(String.fromCharCode(...new Uint8Array( [0,1,2,3] )))
)

/* Always output a random hex hash of here: 30 chars  */
console.log(
  btoa(String.fromCharCode(...new Uint8Array( Array(30).fill().map(() => Math.round(Math.random() * 30)) )))
)

Use HMAC from crypto API, for more: https://stackoverflow.com/a/56416039/2494754

//To return a random letter

let alpha = "ABCDEFGHIGKLMNOPQRSTUVWXYZ";
console.log(alpha.charAt(Math.floor(Math.random() * alpha.length)));
Related