Tom Lehman
Tom Lehman

Reputation: 89333

Generate random string/characters in JavaScript

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?

Upvotes: 2901

Views: 3083535

Answers (30)

Kuza Grave
Kuza Grave

Reputation: 1574

Easy solution:

const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const randomRef = (len = 6) => [...Array(len)].map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join("");

Usage:

console.log(randomRef())    // JzMsHC
console.log(randomRef(16))  // AwN5xObmNKib0nxR

Upvotes: 0

mikakun
mikakun

Reputation: 2265

a one liner without substring :

const getRandom = size => [...Array(size)].map(() => Math.floor(Math.random() * 36).toString(36)).join('');

Upvotes: 2

Ratan Uday Kumar
Ratan Uday Kumar

Reputation: 6512

In below code I am generating random code for 8 characters

function RandomUnique(){
    const charBank = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
    const howmanycharacters = 8;

    let random= '';
    for (let i = 0; i < howmanycharacters ; i++) {
        random+= charBank[parseInt(Math.random() * charBank.length)];
    }

    return random;
}

let random = RandomUnique();
console.log(random);

Upvotes: 0

Terry T&#250; Nguyễn
Terry T&#250; Nguyễn

Reputation: 380

I wrote this to support different usecases:

const CHARS__UPPER_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const CHARS__LOWER_ALPHA = 'abcdefghijklmnopqrstuvwxyz';
const CHARS__NUMBER = '0123456789';

const randomizeString = (length, { alpha = true, number = true, caseSensitive = true } = {}) => {
  let randomString = '';
  let charSpace = '';
  if (alpha) {
    charSpace += CHARS__LOWER_ALPHA;
  }
  if (alpha && caseSensitive) {
    charSpace += CHARS__UPPER_ALPHA;
  }
  if (number) {
    charSpace += CHARS__NUMBER;
  }

  let generatedLength = 0;
  while (generatedLength < length) {
    randomString += charSpace.charAt(Math.floor(Math.random() * charSpace.length));
    generatedLength += 1;
  }
  return randomString;
};

randomizeString(50);
// KshtGCfvYigvcmzCps50s3zmbS62ZnSjK1pJmHAbdWhJUUmr97


randomizeString(50, { alpha: false, number: true });
// 87729472949275732718713685232270378864891972309460


randomizeString(50, { alpha: true, number: true, caseSensitive: false });
// st17zegav3zgk9gt4ki12t6tma1p65oxehsosxjus4ane0xzpz

randomizeString(50, { alpha: true, number: false, caseSensitive: true });
// cjXAsJtcKslkbrAHQfDajQciFFVPopbrbgmoQhzUMxALrUowFP

Upvotes: 0

Felipe Buccioni
Felipe Buccioni

Reputation: 19688

A reduced random alphanumeric with upper and lowercase using random bytes from crypto module:

const l = 98 // length

// Node
Array.from(crypto.randomBytes(l)).reduce((s, b) => s + (b % 36).toString(36)[(b % 2) ? 'toLowerCase' : 'toUpperCase'](), '')

// Browser [WebCrypto] (Thanks to Nabulosar in comments, check his comment if you use it)
Array.from(crypto.getRandomValues(new Uint8Array(l))).reduce((s, b) => s + (b % 36).toString(36)[(b % 2) ? 'toLowerCase' : 'toUpperCase'](), '')

Upvotes: 2

Mulan
Mulan

Reputation: 135396

Math.random is bad for this kind of thing

server side (node, bun)

Use node crypto module -

esm -

import * as crypto from "node:crypto";
const id = crypto.randomBytes(20).toString('hex');

console.log(id)
// "bb5dc8842ca31d4603d6aa11448d1654"

or cjs -

const crypto = require("crypto");
const id = crypto.randomBytes(20).toString('hex');

console.log(id)
// "bb5dc8842ca31d4603d6aa11448d1654"

The resulting string will be twice as long as the random bytes you generate; each byte encoded to hex is 2 characters. 20 bytes will be 40 characters of hex.


client side (browser)

Use the browser's crypto module -

const id = window.crypto.randomUUID()
console.log(id)
// bd4d099b-3d39-4aad-a59c-c45dfac8eaf0

Or crypto.getRandomValues -

The crypto.getRandomValues() method lets you get cryptographically strong random values. The array given as the parameter is filled with random numbers (random in its cryptographic meaning).

// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
function dec2hex (dec) {
  return dec.toString(16).padStart(2, "0")
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"

A step-by-step console example -

> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]

> window.crypto
Crypto { subtle: SubtleCrypto }

> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed

> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]

For IE11 support you can use -

(window.crypto || window.msCrypto).getRandomValues(arr)

For browser coverage see https://caniuse.com/#feat=getrandomvalues


client side (old browsers)

If you must support old browsers, consider something like uuid -

const uuid = require("uuid");
const id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

Upvotes: 982

Reza Mahmoodi
Reza Mahmoodi

Reputation: 726

In one line generate random string with 5 length [a-zA-Z0-9]:

Math.random().toString(36).substring(2,7);

Upvotes: 12

Stephen Quan
Stephen Quan

Reputation: 26214

Whilst this answer is almost similar to others, it differs in that it uses:

  • repeat to create 5 characters (can be generalized to n)
  • replace with regex /./g to replace those 5 characters
  • the formula is random pick a character from a 62 character A-Za-z0-9 string

let ans = "x".repeat(5)
             .replace(/./g, c => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[Math.floor(Math.random() * 62) ] );
console.log(ans);

Upvotes: 21

vineet
vineet

Reputation: 14246

If you're using Lodash or Underscore:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

Upvotes: 18

James Harrington
James Harrington

Reputation: 3226

Here is a test script for the #1 answer (thank you @csharptest.net)

The script runs makeid() 1 million times and as you can see 5 isn't a very unique. running it with a char length of 10 is quite reliable. I've ran it about 50 times and haven't seen a duplicate yet :-)

Note: node stack size limit exceeds around 4 million so you cant run this 5 million times it won't ever finish.

function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

ids ={}
count = 0
for (var i = 0; i < 1000000; i++) {
    tempId = makeid();
    if (typeof ids[tempId] !== 'undefined') {
        ids[tempId]++;
        if (ids[tempId] === 2) {
            count ++;
        }
        count++;
    }else{
        ids[tempId] = 1;
    }
}
console.log("there are "+count+ ' duplicate ids');

Upvotes: 4

nclu
nclu

Reputation: 1059

This will generate a random alpha-numeric string with the length of the first/calling string:

"12345".split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');

//or

String.prototype.rand = function() {return this.split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');};

Upvotes: 2

user1115652
user1115652

Reputation:

This is for firefox chrome code (addons and the like)

function randomBytes( amount )
{
    let bytes = Cc[ '@mozilla.org/security/random-generator;1' ]

        .getService         ( Ci.nsIRandomGenerator )
        .generateRandomBytes( amount, ''            )

    return bytes.reduce( bytes2Number )


    function bytes2Number( previousValue, currentValue, index, array )
    {
      return Math.pow( 256, index ) * currentValue + previousValue
    }
}

Use it as:

let   strlen   = 5
    , radix    = 36
    , filename = randomBytes( strlen ).toString( radix ).splice( - strlen )

Upvotes: 1

Try this, what I use every time:

function myFunction() {
        var hash = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
        var random8 = '';
        for(var i = 0; i < 5; i++){
            random8 += hash[parseInt(Math.random()*hash.length)];
        }
        console.log(random8);
    document.getElementById("demo").innerHTML = "Your 5 character string ===> "+random8;
}        
        
<!DOCTYPE html>
<html>
<body>

<p>Click the button to genarate 5 character random string .</p>

<button onclick="myFunction()">Click me</button>

<p id="demo"></p>



</body>
</html>

Upvotes: 0

Sparw
Sparw

Reputation: 2743

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

Upvotes: 0

Dr.Sai
Dr.Sai

Reputation: 393

In one line

Array.from({ length: 5 }, i => String.fromCharCode(Math.round(Math.ceil(Math.random() * 25) + 65))).join('');

Upvotes: 1

Mulan
Mulan

Reputation: 135396

Here's a functional style approach. The performance is sub-optimal but it was fun to write -

const char = a =>
  String .fromCharCode (a)

const irand = x =>
  Math .floor (Math .random () * x)

const sample = xs =>
  xs .at (irand (xs.length))

const range = x => y =>
  x > y
    ? []
    : [ x, ...range (x + 1) (y) ]

const srand = rs => n =>
  n <= 0
    ? ""
    : char (sample (rs)) + srand (rs) (n - 1)

const identifier = srand ([
  ...range (48) (57),   // include 0-9
  ...range (65) (90),   // include A-Z
  ...range (97) (122),  // include a-z
])

console .log (identifier (6))  //=> xUCXPI
console .log (identifier (10)) //=> JQvct8XeGt
console .log (identifier (20)) //=> ZVDwQSdRQLJEF5Wqjs17

It's hard to beat the clarity of identifier. Maybe a slight improvement could be -

const ord = x =>
  x .charCodeAt (0)

const idGenerator = srand ([
  ...range (ord('0')) (ord('9')),
  ...range (ord('A')) (ord('Z')),
  ...range (ord('a')) (ord('z')),
])

Have fun with it. Let me know what you like/learn ^_^

Upvotes: 7

csharptest.net
csharptest.net

Reputation: 64248

I think this will work for you:

function makeid(length) {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const charactersLength = characters.length;
    let counter = 0;
    while (counter < length) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
      counter += 1;
    }
    return result;
}

console.log(makeid(5));

Upvotes: 3751

Tiago B&#233;rtolo
Tiago B&#233;rtolo

Reputation: 4363

function generateRandomStringLettersAndNumbers(maxLength): string {
  return crypto.randomBytes(maxLength).toString('hex').substring(0, maxLength);
}

Upvotes: 0

Sergio Cabral
Sergio Cabral

Reputation: 6996

To meet requirement [a-zA-Z0-9] and length of 5 characters, use

For Browser:

btoa(Math.random().toString()).substring(10,15);

For NodeJS:

Buffer.from(Math.random().toString()).toString("base64").substring(10,15);

Lowercase letters, uppercase letters, and numbers will occur.

(it's typescript compatible)

Upvotes: 77

gogo
gogo

Reputation: 1011

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"

Upvotes: 25

bendytree
bendytree

Reputation: 13629

Here are some easy one liners. Change new Array(5) to set the length.

Including 0-9a-z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

Including 0-9a-zA-Z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

Codegolfed for ES6 (0-9a-z)

Array(5).fill().map(n=>(Math.random()*36|0).toString(36)).join('')

Upvotes: 39

Or Duan
Or Duan

Reputation: 13860

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.

Upvotes: 139

Tiago Rangel
Tiago Rangel

Reputation: 1337

You can use Web Crypto's API:

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

(original answer here)

Upvotes: 0

Denys Vitali
Denys Vitali

Reputation: 530

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

Upvotes: 4

Arunprasanth M
Arunprasanth M

Reputation: 71

//To return a random letter

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

Upvotes: -4

Gajus
Gajus

Reputation: 73928

function randomString (strLength, charSet) {
    var result = [];
    
    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    
    while (strLength--) { // (note, fixed typo)
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }
    
    return result.join('');
}

This is as clean as it will get. It is fast too, http://jsperf.com/ay-random-string.

Upvotes: 13

Silver Ringvee
Silver Ringvee

Reputation: 5545

Short, easy and reliable

Returns exactly 5 random characters, as opposed to some of the top rated answers found here.

Math.random().toString(36).slice(2, 7);

Upvotes: 341

NVRM
NVRM

Reputation: 13146

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

Upvotes: -1

Victor
Victor

Reputation: 155

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
}

Upvotes: 1

Rick
Rick

Reputation: 325

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;

Upvotes: 2

Related Questions