Reputation: 89333
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
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
Reputation: 2265
a one liner without substring
:
const getRandom = size => [...Array(size)].map(() => Math.floor(Math.random() * 36).toString(36)).join('');
Upvotes: 2
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
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
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
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
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
Reputation: 726
In one line generate random string with 5 length [a-zA-Z0-9]:
Math.random().toString(36).substring(2,7);
Upvotes: 12
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 characterslet ans = "x".repeat(5)
.replace(/./g, c => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[Math.floor(Math.random() * 62) ] );
console.log(ans);
Upvotes: 21
Reputation: 14246
If you're using Lodash or Underscore:
var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');
Upvotes: 18
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
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
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
Reputation: 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
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
Reputation: 393
In one line
Array.from({ length: 5 }, i => String.fromCharCode(Math.round(Math.ceil(Math.random() * 25) + 65))).join('');
Upvotes: 1
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
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
Reputation: 4363
function generateRandomStringLettersAndNumbers(maxLength): string {
return crypto.randomBytes(maxLength).toString('hex').substring(0, maxLength);
}
Upvotes: 0
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
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
Reputation: 13629
Here are some easy one liners. Change new Array(5)
to set the length.
0-9a-z
new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})
0-9a-zA-Z
new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});
0-9a-z
)Array(5).fill().map(n=>(Math.random()*36|0).toString(36)).join('')
Upvotes: 39
Reputation: 13860
A newer version with es6 spread operator:
[...Array(30)].map(() => Math.random().toString(36)[2]).join('')
30
is an arbitrary number, you can pick any token length you want36
is the maximum radix number you can pass to numeric.toString(), which means all numbers and a-z lowercase letters2
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
Reputation: 1337
You can use Web Crypto's API:
console.log(self.crypto.getRandomValues(new Uint32Array(1))[0])
(original answer here)
Upvotes: 0
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
Reputation: 71
//To return a random letter
let alpha = "ABCDEFGHIGKLMNOPQRSTUVWXYZ";
console.log(alpha.charAt(Math.floor(Math.random() * alpha.length)));
Upvotes: -4
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
Reputation: 5545
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
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
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
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