Generate random string/characters in JavaScript
Asked Answered
B

94

2827

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?

Bowker answered 28/8, 2009 at 21:14 Comment(5)
Warning: None of the answers have a true-random result! They are only pseudo-random. When using random strings for protection or security, don't use any of them!!! Try one of these api's: random.orgAllodium
Note HTML5 webcrypto randomness API provides real randomness.Cistercian
If anyone is here looking to generate an id or unique identifier, let your DB do that job or use a UUID library instead.Screwy
random string using javascript,Java, Python, Rust, bashDisplace
Try npm library random-extVaticinate
S
3698

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));
Strapping answered 28/8, 2009 at 21:21 Comment(21)
@dan_waterworth It probably doesn't matter in almost any case: codinghorror.com/blog/2009/01/…Posehn
it may look wrong, but floor is unneeded: for(var text=''; text.length < 5;) text += possible.charAt(Math.random() * possible.length)Illusionist
@dan_waterworth, Actually, += is often faster for some reason, even used inside loops - jsperf.com/join-vs-concatenationDevlin
@AlexReece That link doesn't say what you think it says. Doing "a"+"b" a million times is fine. Doing a += "b" a million times is not.Maddeu
@JonathanPaulson Show me the numbers. See the previous comment with a jsperf link or jsperf.com/sad-tragedy-of-microoptimization or sitepen.com/blog/2008/05/09/string-performance-an-analysis etc. Also, this question involves only 5 concatenations.Posehn
Thanks! I used this but randomized the length. Instead of 5, I got another random number for length: Math.floor(Math.random() * maxLength)Turtledove
@dan_waterworth - what you've said is true in other languages, not in javascript.Granddaddy
so i just crunched some numbers (ran it about 10 million times) and with 5 characters you get about a 0.05% duplication pretty consistently when you up the characters by even one that % drops to about 0.0001%. i plan on using this in my password salting and i will use a 10 character rand string and i think it will be perfect!Silly
@codenamejames Please do not use this in your password salting. It is only pseudo-random not secure. Assuming you are using Node (I'm not even sure where to start if you're salting on the client side), use crypto instead.Shewmaker
@Shewmaker what about getRandomValues?Granophyre
@JanusTroelsen crypto.getRandomValues will work; it does provide crypto-strong numbers, although it didn't exist at the time of my comment.Shewmaker
Is there any easy way to have those chars unique always?Abigael
@Shewmaker the salt used on a password can usually be assumed to be public information, and doesn't need to be cryptographically secure. It's there purely to reduce the risk of a pre-computed rainbow table existing.Deviation
What is this irrelevant discussion about performance? Who wants to generate a random string of a million characters? And if in 2017 we still have to peek under the hood when writing string concatenation, we haven't made any progress at all.Bennettbenni
@HaiPhan lmao, too right. Didn't matter to me 8 years ago, damn sure doesn't now 😆Strapping
the v8 engine optimises the creation of strings based on older ones and so it isn't O(n^2)Degreeday
I like this because it's really concise, easy to understand and doesn't use any libraries or advanced ecmascript features.Rundlet
@dan_waterworth it only matters if you generate like 10 million character long strings lolSubdue
you can your pass : console.log("MZ-"+makeid(2)+"15");Raddatz
Actually, in modern browsers string concatenation is 2-3 times faster than joining an array: jsben.ch/FCQ9w (which, I agree, would not matter in almost any case anyway). I modified the code snippet to use string concatenation.Torre
I think @Mulan's answer below is better than this I think, which uses crypto lib crypto.randomBytes(20).toString('hex');Ignace
A
3177

//Can change 7 to 2 for longer results.
let r = (Math.random() + 1).toString(36).substring(7);
console.log("random", r);

Note: The above algorithm has the following weaknesses:

  • It will generate anywhere between 0 and 6 characters due to the fact that trailing zeros get removed when stringifying floating points.
  • It depends deeply on the algorithm used to stringify floating point numbers, which is horrifically complex. (See the paper "How to Print Floating-Point Numbers Accurately".)
  • Math.random() may produce predictable ("random-looking" but not really random) output depending on the implementation. The resulting string is not suitable when you need to guarantee uniqueness or unpredictability.
  • Even if it produced 6 uniformly random, unpredictable characters, you can expect to see a duplicate after generating only about 50,000 strings, due to the birthday paradox. (sqrt(36^6) = 46656)
Affinitive answered 10/11, 2011 at 18:12 Comment(23)
love it, but he needs [a-zA-Z]Broadfaced
Math.random().toString(36).substr(2, 5), because .substring(7) causes it to be longer than 5 characters. Full points, still!Tier
And an ActionScript 2 compatible version: Math.round(Math.random()*Math.pow(36,5)).toString(36)Whaler
@Scoop The toString method of a number type in javascript takes an optional parameter to convert the number into a given base. If you pass two, for example, you'll see your number represented in binary. Similar to hex (base 16), base 36 uses letters to represent digits beyond 9. By converting a random number to base 36, you'll wind up with a bunch of seemingly random letters and numbers.Ironsides
Looks beautiful but in few cases this generates empty string! If random returns 0, 0.5, 0.25, 0.125... will result in empty or short string.Brancusi
This produces a longer random number: (Math.PI * Math.max(0.01, Math.random())).toString(36).substr(2, 5);Sharkskin
@Brancusi This can be avoided by (Math.random() + 1).toString(36).substring(7);Ahoufe
To summarise, the ultimate script using @GeorgeReith and dragon's techniques is: (Math.random() +1).toString(36).substr(2, 5). It stops the string being empty and limits it to 5 chars.Implantation
@william44isme: If Math.random() returns 0.25, then the above will evaluate to (1.25).toString(36).substr(2, 5), which will equal 9 - so it still won't work. I did this: function randomString() { var i = ''; while(i.length < 5) {i = Math.random().toString(36).slice(2);}; return i; }, which gets me a string of at least 5Cristencristi
@AsfandYarQazi I'm not sure what the pattern is for producing such small strings so if anyone could explain that would be great. Although your solution (and adds some entropy in variation of token length) looks good and is what I am currently using.Ahoufe
"0" fix: ('0000'+Math.random().toString(36).replace('.', '')).substr(-5);Internode
This solution only partly answers the question. It will generate a random string of parts [a-z0-9]. It will not include capital letters. Still a very good trick nonetheless!Xebec
(+new Date * Math.random()).toString(36).substring(0,5)Hidie
I don't know if it's useless, but hacklikecrack is totally telling the truth. csharptest.net's algorithm generates far less duplicates. If you crank up the number of digits to 8, you'll find the duplicates drop to zero. thank you @hacklikecrackEpp
Nice solution. However, I would rather use slice, so that the number of characters matches the given parameter. Math.random().toString(36).slice(-5)Globulin
@hacklikecrack, the duplicates occur because substring(7) takes the digits from the least significant part of the base-36 string. toString(36) appears to convert the random number to a 16 digit base-36 string, but the precision required for this would be 36^16 = 7.958e24 possible numbers, where the precision of Math.random() is only 4.5e15. Taking the digits from most significant end with .slice(2,5) solves this: 5 digit exampleWombat
This might not work as expected in newer versions of Chrome (thenextweb.com/google/2015/12/17/…)Glycol
length => (Math.random().toString(36).substring(2, 2 + length) + '0'.repeat(length)).substring(0, length)Kerseymere
All these comments make it pretty confusing as to what the actual best solution is here and whether the highly upvoted answer above is indeed the best direction, or one of the ones in the comments like this: Math.random().toString(36).substr(2, 5) ?Platform
I wrote this answer almost 9 years ago as a knee-jerk reaction to not show exactly the right answer (my mistake in intention) but to show only a potentially different way of thinking about the problem. At the time there was no answer similar to mine. Based on the comments above here, I think I accomplished my goal.Affinitive
Not really helpful answer, yet too many up votes! it has too many issues.Windpollinated
If Math.random returns 0.5 then we get invalid resultPera
Keep in mind that String.prototype.substr() is deprecated. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Rebound
D
933

Math.random is bad for this kind of thing

server side

Use node crypto module -

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

// "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

Use the browser's crypto module, 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"
Delighted answered 2/1, 2015 at 19:18 Comment(22)
Note that for version 4 UUIDs, not all the characters are random. From Wikipedia: "Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B". (en.wikipedia.org/wiki/…)Concrescence
@wmassingham, I'm not sure I understand the purpose of your comment. Do you mean to imply something the concern of uniqueness due to some fixed characters in a v4 uuid ?Delighted
Exactly. While a UUID is fine for assigning an ID to a thing, using it as a string of random characters isn't a great idea for this (and probably other) reasons.Concrescence
Safari 9.3 shows this error: SyntaxError: Unexpected token '>'Excavate
@RonaldoBahia, Safari doesn't support arrow functions because it's a noob. Thanks for the notice.Delighted
crypto is the way to go if you are using Node.js. This deserves more upvotes.Colleencollege
No need for .map() in Option 3. Array.from(arr, dec2hex).join('') === Array.from(arr).map(dec2hex).join(''). Thanks for introducing me to these features :-)Chirurgeon
should mention that synchronous version throws an Error unlike the async version which follows callback(err, data) convention.Anthropogeography
You should mention in the answer that option 2 also needs node.js to work, it's not pure javascript.Exemplificative
@Exemplificative node is used to create the front-end module but the result is pure javascript that runs directly in the browser. Packaging javascript using node is commonplace and there are countless utilities to help automate the task for you. However they are beyond the scope of this answer.Delighted
For option 3, I would prefer something like this: function generateId(len) {var arr = new Uint8Array(len); window.crypto.getRandomValues(arr); return Array.from(arr, function(dec) { return Math.floor(dec / 16).toString(16); }).join('');}Samantha
Also notice that IE 11 doesn't support Array.from, but it does support window.crypto.getRandomValues.Samantha
While being more cryptographically secure, this doesn't actually satisfy the requirements of the question because it only outputs 0-9 and a-f (Hexadecimal), and not 0-9, a-z, A-Z.Jaunty
('0' + dec.toString(16)).substr(-2) now has a nicer form: dec.toString(16).padStart(2, '0')Made
What if I need a random string in the set [a-zA-Z0-9] of length N?Clorindaclorinde
@Clorindaclorinde write a program to do it? Array.from(Array(N), _ => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".substr(Math.floor(Math.random() * 62), 1)).join("")Delighted
@thank-you But as you suggested, I wanted to use cryptographic uniqueness.Clorindaclorinde
I am using a node package, similar to your answer. const cryptoRandomString = require('crypto-random-string'); cryptoRandomString({length: 100, type: 'base64'}).replace(/[/+=]/g,'').substr(-30); I am generating a random base64 string of 100 characters. Then taking last 30 characters after removing unwanted characters (+,/,=).Clorindaclorinde
Beware, the dec2hex() function is wrong (unless you actually want 15 to map to f instead of 0f. To fix the function, the conditional must be updated to dec < 16 from dec < 10. However, one could just go for more concise form already suggested by Amadan in a former comment: dec.toString(16).padStart(2, '0')Carder
@Carder the dec2hex was provided an example encoder. It's up to you to represent the bytes however you choose. I updated the post with your suggestion.Delighted
@Delighted crypto is available to browsers as well. See caniusePolysepalous
@Polysepalous thanks that was option 3 in the post. i reworded things to make it a little more clear that it was a browser module.Delighted
P
325

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);
Pelletier answered 27/7, 2016 at 20:24 Comment(18)
What if Math.random().toString(36) returns a number with less than 5 characters?Gorizia
SilverRingvee probably just copy-pasted the comment from @Tier in the second answer. Give credit when it's due.Carrick
Well, that's an interesting indictment from @Aperçu, I am not saying that I invented the solution but I've been using it in my projects for years now. And it has nothing to do with the comment you mentioned. And I am quite sure that in SO what matters is the most useful information in the right place and even if it already exists in some other place, too. Luckily, it seems like at least 51 guys have found this answer useful, you're welcome!Pelletier
As @MichaelLitvin pointed out, this fails in certain instances. Two examples are when Math.random() returns 0 or 1. In these cases, the result of the expression provided in this answer is simply "". :(Enrollee
To avoid getting empty string in case of Math.random() returns 0 you can use function getRandomString() { var result = ''; while (!result) result = Math.random().toString(36).substring(2); return result; };Attlee
@Enrollee Math.random() can return 0 but not 1 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Attlee
Good to know, @mikep! Still, that's at least one case (there may be more) in which this code is broken. If nothing else, it needs a conditional about the "0 case" which makes this a little bit less "short and easy" :/Enrollee
This method does seem to be limited to (a max) of 10 characters.... still cool though.Transcendentalistic
I ran this code 1,000,000,000 times and still didn't get an empty string: jsfiddle.net/mtp5730r I would say you're pretty safe from getting an empty string.Crumple
Is this OK? What if I want more than 5 characters (not what the question asks, but a reasonable use case for someone reading this question IMO)? How many characters can result from passing the result of Math.random() through toString(36)? I can probably find out, but I would imagine that the number of characters and the quality of randomness depend on the tricky details of how floating-point numbers work in Javascript. I wouldn't feel confident depending on this.Heliocentric
An event being statistically unlikely does not make it safe. If anyone is using this for any security related activity they are gambling on the improbability of Math.random not returning 0. Hope you never have to debug this eventBeatriz
This does not always return 5 characters. For example, (0.5).toString(36).substr(2, 5) yields "i".Enrollee
Note that substr is a 'legacy function' in Node.js, so I used .slice(2, 5).Linker
@Linker I don't think the question mentioned Node.js anywhere.Pelletier
@SilverRingvee Modern IDEs will mark substr() as deprecated in both Node and vanilla JS/TypeScript so @Linker has a point.Eanes
@Beatriz I'm sorry, but the entire industry of technological security is based on the premise that extremely unlikely=safe. With that argument, nothing is ever safe because they could just guess your privatekey/password/hash/etc. The only question is how unlikely is it, and is that unlikely enough for your application.Gibb
@SepehrNazari I dont see you disagreeing with my comment so I dont know if you expected a reply or not... I still hope that neither you nor OP dont have to debug that caseBeatriz
Like it. Put it in a loop with a "test+=", and was able to get a 20 digit random code. Might not be "secure", but as it's only to be used to create a fake offline ClickBank receipt number ...Bobbiebobbin
R
191

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.

Reglet answered 13/11, 2013 at 21:18 Comment(8)
Why not just add 1? (Math.random()+1).toString(36).substring(7);Pitta
Because adding 1 doesn't solve either of the two issues discussed here. For example, (1).toString(36).substring(7) produces an empty string.Reglet
Using Math.random().toString(36).substring(2,7) gives an expected result which is more like the .substring(2, n+2)Sadiras
Array.apply(null, {length: 5}).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('')Vascular
This is great, but when executed in Firefox with N=16, the last ~6 digits end up being zero... (But it does satisfy the OP's desire for 5 random chars though.)Peddada
@EdwardNewell That is a correct observation about Firefox and N > 11, although the solution and explanation are basically the same - specifically, using large N does not add any randomness, but does guarantee an exact string length, which the original solution lacked. I'll update the answer.Reglet
The updated part of this post is great, it passes the test described in stackoverflow.com/questions/1349404/… just fine and it is just as fast as the hacky approach.Offside
this leads to substrings repetitionTranscription
A
160

The most compact solution, because slice is shorter than substring. Subtracting from the end of the string allows to avoid floating point symbol generated by the random function:

Math.random().toString(36).slice(-5);

or even

(+new Date).toString(36).slice(-5);

Update: Added one more approach using btoa method:

btoa(Math.random()).slice(0, 5);
btoa(+new Date).slice(-7, -2);
btoa(+new Date).substr(-7, 5);

// Using Math.random and Base 36:
console.log(Math.random().toString(36).slice(-5));

// Using new Date and Base 36:
console.log((+new Date).toString(36).slice(-5));

// Using Math.random and Base 64 (btoa):
console.log(btoa(Math.random()).slice(0, 5));

// Using new Date and Base 64 (btoa):
console.log(btoa(+new Date).slice(-7, -2));
console.log(btoa(+new Date).substr(-7, 5));
Aileenailene answered 15/10, 2015 at 11:11 Comment(7)
Math.random().toString(36).slice(-5); - What if Math.random() returns 0.0?Sonata
@x-ray, you will get "0" ;)Aileenailene
Exactly. ;) And if Math.random() returns 0.5 the result is "0.i". Not sure if there are other edge cases. Just wanted to point out that this is not a correct answer to the question (5 characters from [a-zA-Z0-9]).Sonata
@x-ray, I'm not going to say that this is the right answer, I'm just saying that this is a compact version of the @Affinitive answer above. I personally use (+new Date + Math.random()) to prevent this case. Anyway, thanks for the note.Aileenailene
I would not recommend using btoa especially not tie it to a date for a variety of reasons. The mains ones are 1) It is reversible! Someone with that string could know when you generate it 2) It is predictable! With one string I could guess the next ones 3) Generating the string on the same second result the same token. 4) It doesn't use all chars since the date doesn't change that much.Danialdaniala
Why not using bota at all? I commented on other answers but using this test case you can see you going to use only 14 chars out of 64 that base64 has to offer: [...new Set([...Array(100000)].map(()=>btoa(Math.random()).substr(0, 5)).join(""))].sort()Danialdaniala
This gave me the same result in two different places after about 20 runs. Don't use.Arzola
D
136

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.
Danialdaniala answered 26/11, 2017 at 13:17 Comment(6)
Could you explain? Especially why you pass 36 to toString() and why you choose the 3rd element?Hynes
nice, but this solution doesn't include [A-Z] characters as question requested, only [a-z0-9]Integration
@NahuelGreco you can do [...Array(30)].map(() => Math.random().toString(36)[2]).join('').toUpperCase()Shellbark
@Shellbark I think no, original question asked for mixed caps, each char must be chosen at random from the [a-zA-Z0-9] set. This answer doesn't satisfies that.Integration
Array(30).fill().map(() => Math.random().toString(36).slice(2)).join('') to generate a huge random stringDispraise
I would also add a || '0' so that it falls back to 0 instead of undefined if Math.random() returns 0 (it never returns 1)Allison
G
119

Something like this should work

function randomString(len, charSet) {
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var randomString = '';
    for (var i = 0; i < len; i++) {
        var randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

Call with default charset [a-zA-Z0-9] or send in your own:

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');
Gramps answered 28/8, 2009 at 21:28 Comment(5)
A variant of example here can be found here: mediacollege.com/internet/javascript/number/random.htmlTelex
might as well just decrement len directly in a while loopMotheaten
Thanks, I just posted below a coffeescript variation of this example: https://mcmap.net/q/20680/-generate-random-string-characters-in-javascriptDijon
If these are going to be used publically, then you should probably remove the vowels. A little less entropy, but a lot safer as you can't generate any words that may offend people. That is why I like this, since I can send in my own character string. Good job.Kristinakristine
note that on a Node server, it's this simple: crypto.randomBytes(3).toString('hex') (3 bytes gives 6 chars, for example)Bivens
M
78

function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));
Melvinmelvina answered 29/8, 2009 at 2:41 Comment(4)
I like this the best. You could easily modify to accept extra parameters and return only nums, lowers, or caps. I don't think the ultra-compressed style is necessary while(s.length< L) s+= randomchar();Mastoiditis
Also while(L--) will do itGranddaddy
Better to use the more robust 'A'.charCodeAt(0) rather than the magic number 55 (and likewise for the 61). Particularly since, on my platform anyway, the magic number that returns is 65. That code will self-document better as well.Arnoldoarnon
I created a minification optimized (46 bytes smaller) variant of your implementation here: stackoverflow.com/a/52412162Bartolommeo
C
75

Random String Generator (Alpha-Numeric | Alpha | Numeric)

/**
 * Pseudo-random string generator
 * https://mcmap.net/q/20680/-generate-random-string-characters-in-javascript
 * Default: return a random alpha-numeric string
 * 
 * @param {Integer} len Desired length
 * @param {String} an Optional (alphanumeric), "a" (alpha), "n" (numeric)
 * @return {String}
 */
function randomString(len, an) {
  an = an && an.toLowerCase();
  var str = "",
    i = 0,
    min = an == "a" ? 10 : 0,
    max = an == "n" ? 10 : 62;
  for (; i++ < len;) {
    var r = Math.random() * (max - min) + min << 0;
    str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
  }
  return str;
}

console.log(randomString(10));      // i.e: "4Z8iNQag9v"
console.log(randomString(10, "a")); // i.e: "aUkZuHNcWw"
console.log(randomString(10, "n")); // i.e: "9055739230"

While the above uses additional checks for the desired A/N, A, N output, let's break it down the to the essentials (Alpha-Numeric only) for a better understanding:

  • Create a function that accepts an argument (desired length of the random String result)
  • Create an empty string like var str = ""; to concatenate random characters
  • Inside a loop create a rand index number from 0 to 61 (0..9+A..Z+a..z = 62)
  • Create a conditional logic to Adjust/fix rand (since it's 0..61) incrementing it by some number (see examples below) to get back the right CharCode number and the related Character.
  • Inside the loop concatenate to str a String.fromCharCode( incremented rand )

Let's picture the ASCII Character table ranges:

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor( Math.random * 62 ) gives a range from 0..61 (what we need).
Let's fix the random to get the correct charCode ranges:

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

The conditional operation logic from the table above:

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

From the explanation above, here's the resulting alpha-numeric snippet:

function randomString(len) {
  var str = "";                                // String result
  for (var i = 0; i < len; i++) {              // Loop `len` times
    var rand = Math.floor(Math.random() * 62); // random: 0..61
    var charCode = rand += rand > 9 ? (rand < 36 ? 55 : 61) : 48; // Get correct charCode
    str += String.fromCharCode(charCode);      // add Character to str
  }
  return str; // After all loops are done, return the concatenated string
}

console.log(randomString(10)); // i.e: "7GL9F0ne6t"

Or if you will:

const randomString = (n, r='') => {
  while (n--) r += String.fromCharCode((r=Math.random()*62|0, r+=r>9?(r<36?55:61):48));
  return r;
};

console.log(randomString(10))
Condone answered 10/1, 2015 at 2:9 Comment(1)
For a reason I was not able to identify, x.toString(36) --- as is used in the above answers --- was not reliably generating the same characters when I compared the outputs of two apps that had different ES versions, and this function fixed this for me as it does not use .toString()!Galenism
F
73

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)

Flatiron answered 18/6, 2018 at 1:50 Comment(7)
I guess, Math.random() could lead to a base64-string with too few characters.Doxy
Adding on @Doxy comment, this will only generate numbers between 1-5 and only 19 out of 52 letters!(upper and lower case) To test just run it multiple time, Set it to see unique chars and then sort. one liner for that: [...new Set([...Array(100000)].map(()=>btoa(Math.random()).substr(5, 5)).join(""))].sort()Danialdaniala
Why do we need toString in the browser example?Hinder
You're right. No need for toString(). But as I wanted to do something as "it's typescript compatible". So I left it that way.Flatiron
Math.random().toString() will only use digits 0-9 which is anything but random. You cant just base64 it and expect it to be random. You need random seed data to create a random output. Therefor this answer fails to answer the OPs question.Hildehildebrand
Phil, are you saying that the Math.random() function is not random? LOL numbers 0 to 9 have a smaller universe of variety, but they ARE random using Math.random()Flatiron
can we use .substing(10,15) instead?Exegetics
M
45

The simplest way is:

(new Date%9e6).toString(36)

This generate random strings of 5 characters based on the current time. Example output is 4mtxj or 4mv90 or 4mwp1

The problem with this is that if you call it two times on the same second, it will generate the same string.

The safer way is:

(0|Math.random()*9e6).toString(36)

This will generate a random string of 4 or 5 characters, always diferent. Example output is like 30jzm or 1r591 or 4su1a

In both ways the first part generate a random number. The .toString(36) part cast the number to a base36 (alphadecimal) representation of it.

Militate answered 11/3, 2015 at 21:43 Comment(7)
I'm not quite sure how this answers the question; This is a 7 year old question with many valid answers already. If you choose to provide a new answer, you should really take extra care to make sure that your answer is well explained and documented.Pearle
If you use Date, why don't you just use it like: (+new Date).toString(36)Hanshaw
I like your random number solution but 9e6 gives only 9 millions possibilities over the 60.4 millions ones for 5 digits (36^5) so you could replace it with (0|Math.random()*6.04e7).toString(36) to cover it.Daegal
I wanted a longish random string with a short-as-possible routine (for a code demo) that doesn't need to be cryptographically amazing, just produce some nice random visual "fluff". I like this answer the best (your 2nd one), so thank you. My two cents: I can beat it for shortness with one less keystroke, and it will typically produce 13 random characters (without a period): (Math.random()*1e20).toString(36).Coxa
one qualm I have with this answer is that it will not use [A-Z] which happens to be in the original question.Transcendentalistic
The "simplest way" doesn't create random strings at all; it creates highly predictable strings with the superficial appearance of being random.Midrib
This should not be used if you need more than one string at a time. Date only has millisecond precision, so you can easily generate thousands of identical strings before the next millisecond ticks over.Fraser
C
37

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('')
Carlottacarlovingian answered 17/7, 2014 at 17:47 Comment(0)
L
28

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
Longshore answered 28/9, 2021 at 1:25 Comment(0)
C
26

I know everyone has got it right already, but i felt like having a go at this one in the most lightweight way possible(light on code, not CPU):

function rand(length, current) {
  current = current ? current : '';
  return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
}

console.log(rand(5));

It takes a bit of time to wrap your head around, but I think it really shows how awesome javascript's syntax is.

Categorize answered 4/5, 2011 at 15:0 Comment(3)
If you're trying to keep the code short, why write current = current ? current : ''; when you can write current = current || '';Gramps
since we're talking micro optimization here i would actually suggest to skip the variable assignment entirely if not necessary: current || (current = '');Phoenicia
Attempting micro optimization while using a "nice" but resource wasting recursive algorithm makes no sense :-) A for loop still is best in Javascript and beats recursion big time, until really big advances in the optimizing code of the runtimes are made.Ne
R
25

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"
Refinement answered 11/8, 2020 at 17:45 Comment(0)
N
19

In case anyone is interested in a one-liner (although not formatted as such for your convenience) that allocates the memory at once (but note that for small strings it really does not matter) here is how to do it:

Array.apply(0, Array(5)).map(function() {
    return (function(charset){
        return charset.charAt(Math.floor(Math.random() * charset.length))
    }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')

You can replace 5 by the length of the string you want. Thanks to @AriyaHidayat in this post for the solution to the map function not working on the sparse array created by Array(5).

Nosography answered 18/2, 2013 at 19:56 Comment(1)
Every javascript program is a 'one-liner' if you format it as suchTowns
T
19

If you're using Lodash or Underscore:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');
Tallu answered 20/4, 2016 at 5:39 Comment(2)
Lodash uses _.sampleSize('asdfgh',5).join('')Frizz
This actually is not a good solution, because per docs each character is from a unique index. That means it's not truly random, since no character can / will ever repeat.Breechcloth
I
17
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')
Integration answered 31/5, 2019 at 17:37 Comment(0)
C
15

Here's the method I created.
It will create a string containing both uppercase and lowercase characters.
In addition I've included the function that will created an alphanumeric string too.

Working examples:
http://jsfiddle.net/greatbigmassive/vhsxs/ (alpha only)
http://jsfiddle.net/greatbigmassive/PJwg8/ (alphanumeric)

function randString(x){
    var s = "";
    while(s.length<x&&x>0){
        var r = Math.random();
        s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
    }
    return s;
}

Upgrade July 2015
This does the same thing but makes more sense and includes all letters.

var s = "";
while(s.length<x&&x>0){
    v = Math.random()<0.5?32:0;
    s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
}
Camembert answered 28/8, 2013 at 14:50 Comment(2)
With this function, you can never get an uppercase letter greater than 'M' or a lowercase letter lesser than 'n'.Helium
Really? ooh! will probably test it more then. Hmm, however, given it's a random string and we don't really care what letters are in it (as long as they are random) then it still does what we want it to do which is all that matters but yes, will provide an upgrade, thanks.Camembert
Q
15

One liner:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil
Queen answered 20/3, 2020 at 22:9 Comment(3)
To make it shorter change argument in Array(15) to a smaller value. E.g.: Array(4).Queen
I really love this solution, simple and clear. It is generating 15 random numbers between 0 and 1, generate the hexadecimal, and then remove the first two chars. Finally it is merging all of them together.Polyandry
erroneous solution, uppercase characters aren't generated.Integration
F
15

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.

Falco answered 24/7, 2020 at 21:32 Comment(0)
Z
14

Assuming you use underscorejs it's possible to elegantly generate random string in just two lines:

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');
Zobias answered 18/5, 2015 at 11:48 Comment(1)
This will make the returned value have all unique chars. Also, the length of the string is limited up to the the length of var possible.Yezd
A
14

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);
Achates answered 13/2, 2023 at 3:57 Comment(0)
Z
13
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.

Zennas answered 10/1, 2013 at 1:39 Comment(4)
For me this always generates random strings with strLength - 1 :-/Oculo
Switching from --strLength to strLength--fixes it for me.Oculo
@Zennas I took the liberty of fixing the obvious typo. it is strLength-- postfix, not prefix.Bivens
thank you sir. Wrapping it in a func make it easy to copy/paste ❤️Delate
K
11

Fast and improved algorithm. Does not guarantee uniform (see comments).

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    let result = '';

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}
Kwiatkowski answered 16/9, 2016 at 16:36 Comment(2)
Great answer, but probability is not uniform. There are 62 possible characters and crypto.getRandomValues returns one of 256 unique values. Because 256 is not divided by 62, you end up having slightly higher probability of getting characters A-H. I think the best solution is to do what YouTube did, and just add 2 additional characters (possibly - and _) to the charset. Anyway, great work - this answer needs so much more love :)Tamar
adding - and _ is a great idea since it will get you the complete url-safe base64 setElbring
J
10

You can loop through an array of items and recursively add them to a string variable, for instance if you wanted a random DNA sequence:

function randomDNA(len) {
  len = len || 100
  var nuc = new Array("A", "T", "C", "G")
  var i = 0
  var n = 0
  s = ''
  while (i <= len - 1) {
    n = Math.floor(Math.random() * 4)
    s += nuc[n]
    i++
  }
  return s
}

console.log(randomDNA(5));
Jessen answered 1/1, 2012 at 21:24 Comment(0)
C
10

How about this compact little trick?

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var stringLength = 5;

function pickRandom() {
    return possible[Math.floor(Math.random() * possible.length)];
}

var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

You need the Array.apply there to trick the empty array into being an array of undefineds.

If you're coding for ES2015, then building the array is a little simpler:

var randomString = Array.from({ length: stringLength }, pickRandom).join('');
Cliffordclift answered 8/8, 2013 at 8:4 Comment(0)
M
10

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
Marquise answered 23/9, 2018 at 8:46 Comment(1)
This answer has fit more for my use case. It would be cool if you could add a var possible like in the accepted answer, so the outcome of the function is more configurable.Convenience
D
9

The problem with responses to "I need random strings" questions (in whatever language) is practically every solution uses a flawed primary specification of string length. The questions themselves rarely reveal why the random strings are needed, but I would challenge you rarely need random strings of length, say 8. What you invariably need is some number of unique strings, for example, to use as identifiers for some purpose.

There are two leading ways to get strictly unique strings: deterministically (which is not random) and store/compare (which is onerous). What do we do? We give up the ghost. We go with probabilistic uniqueness instead. That is, we accept that there is some (however small) risk that our strings won't be unique. This is where understanding collision probability and entropy are helpful.

So I'll rephrase the invariable need as needing some number of strings with a small risk of repeat. As a concrete example, let's say you want to generate a potential of 5 million IDs. You don't want to store and compare each new string, and you want them to be random, so you accept some risk of repeat. As example, let's say a risk of less than 1 in a trillion chance of repeat. So what length of string do you need? Well, that question is underspecified as it depends on the characters used. But more importantly, it's misguided. What you need is a specification of the entropy of the strings, not their length. Entropy can be directly related to the probability of a repeat in some number of strings. String length can't.

And this is where a library like EntropyString can help. To generate random IDs that have less than 1 in a trillion chance of repeat in 5 million strings using entropy-string:

import {Random, Entropy} from 'entropy-string'

const random = new Random()
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-string uses a character set with 32 characters by default. There are other predefined characters sets, and you can specify your own characters as well. For example, generating IDs with the same entropy as above but using hex characters:

import {Random, Entropy, charSet16} from './entropy-string'

const random = new Random(charSet16)
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"27b33372ade513715481f"

Note the difference in string length due to the difference in total number of characters in the character set used. The risk of repeat in the specified number of potential strings is the same. The string lengths are not. And best of all, the risk of repeat and the potential number of strings is explicit. No more guessing with string length.

Dynamism answered 2/9, 2017 at 21:10 Comment(1)
Thanks! Your comment made me realize I shouldn't be generating IDs randomly. It looks like nanoid is much more popular than entropy-string and seems just as good for my purposes.Catullus
T
9

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

Tessietessier answered 21/6, 2020 at 20:54 Comment(0)
D
7

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 ^_^

Delighted answered 1/7, 2016 at 21:3 Comment(4)
Great solution and I like that you derive fold from foldk :DLakisha
What are U, Y and foldk? I'm trying to understand this but I'm not that familiar with functional programming and, in all honesty, have no idea what to look up. Also, I did a benchmark using Deno to compare this method with the equivalent imperative one and, as suspected, it is 4x slower 😃Solfatara
@TeodorMaxim to understand U and Y you will have to look into combinatory logic. foldk is a variant of fold (or reduce) which uses continuation-passing style. I re-worked the answer to be more practical and less concerned with functional primitives. You will find the performance to be greatly improved in this revision. Let me know if you have any other questions.Delighted
I used const irand = x => { let value: number | undefined const arr = new Uint8Array(1) while (value === undefined || value >= x) { self.crypto.getRandomValues(arr) value = arr.at(0) } return value } to avoid Math.random. But blocks of code does not whow well in comments...Overreact
S
7

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.

Sasnett answered 5/2, 2018 at 21:17 Comment(0)
S
7

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))
Sidelight answered 21/7, 2021 at 13:25 Comment(0)
Z
7

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)],
    "",
  );
Zoochemistry answered 12/10, 2021 at 13:44 Comment(0)
G
6

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
Gasparo answered 24/4, 2019 at 19:17 Comment(0)
M
5

This works for sure

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>
Morsel answered 3/12, 2009 at 8:48 Comment(0)
L
5

Generate 10 characters long string. Length is set by parameter (default 10).

function random_string_generator(len) {
var len = len || 10;
var str = '';
var i = 0;

for(i=0; i<len; i++) {
    switch(Math.floor(Math.random()*3+1)) {
        case 1: // digit
            str += (Math.floor(Math.random()*9)).toString();
        break;

        case 2: // small letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 97); //'a'.charCodeAt(0));
        break;

        case 3: // big letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 65); //'A'.charCodeAt(0));
        break;

        default:
        break;
    }
}
return str;
}
Lavery answered 11/1, 2013 at 10:54 Comment(0)
M
4

This is what I used. A combination of a couple here. I use it in a loop, and each ID it produces is unique. It might not be 5 characters, but it's guaranteed unique.

var newId =
    "randomid_" +
    (Math.random() / +new Date()).toString(36).replace(/[^a-z]+/g, '');
Mazza answered 22/9, 2013 at 19:55 Comment(1)
For what it's worth, this is not guaranteed unique, it is just very likely to be unique. Consider that Math.random() might return zero twice. Moreover, if two different base-36 numbers being fed into .replace(/[^a-z]+/g, ''); have the same sequence of non-numeric characters (e.g. abc1 and abc2), they will return the same ID.Mensurable
S
4

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');
Silly answered 7/8, 2014 at 2:8 Comment(0)
M
4

You can use coderain. It's a library to generate random codes according to given pattern. Use # as a placeholder for upper and lowercase characters as well as digits:

var cr = new CodeRain("#####");
console.log(cr.next());

There are other placeholders like A for uppercase letters or 9 for digits.

What may be useful is that calling .next() will always give you a unique result so you don't have to worry about duplicates.

Here is a demo application that generates a list of unique random codes.

Full disclosure: I'm the author of coderain.

Mansard answered 9/1, 2017 at 14:54 Comment(1)
NO NO NO - use native methods.Papuan
M
4

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.

Menell answered 2/10, 2017 at 13:31 Comment(0)
M
4

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

Mccaleb answered 16/11, 2017 at 14:21 Comment(1)
Unfortunately this won’t be unique, as Date.now() only has millisecond resolution. When run in a simple loop, for example, you’ll get lots of duplicates. for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); }.Inquiry
P
4

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('')
}
Programme answered 27/2, 2021 at 16:56 Comment(1)
The set should be [a-zA-Z0-9]Zoochemistry
B
4

One liner [a-z]:

String.fromCharCode(97 + Math.floor(Math.random() * 26))
Barfield answered 21/5, 2021 at 16:1 Comment(1)
You still need to compose the string to the length it was asked. And this only generates random characters from [a-b] lowercase. What about uppercase and numbers as it was asked as well on the question?Commorancy
S
4

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('');
Smock answered 9/6, 2021 at 9:17 Comment(0)
N
3

Expanding on Doubletap's elegant example by answering the issues Gertas and Dragon brought up. Simply add in a while loop to test for those rare null circumstances, and limit the characters to five.

function rndStr() {
    x=Math.random().toString(36).substring(7).substr(0,5);
    while (x.length!=5){
        x=Math.random().toString(36).substring(7).substr(0,5);
    }
    return x;
}

Here's a jsfiddle alerting you with a result: http://jsfiddle.net/pLJJ7/

Naxos answered 17/3, 2013 at 0:44 Comment(0)
B
2

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('');};
Bludge answered 20/3, 2013 at 17:13 Comment(0)
C
2

Also based upon doubletap's answer, this one handles any length of random required characters (lower only), and keeps generating random numbers until enough characters have been collected.

function randomChars(len) {
    var chars = '';

    while (chars.length < len) {
        chars += Math.random().toString(36).substring(2);
    }

    // Remove unnecessary additional characters.
    return chars.substring(0, len);
}
Cliffordclift answered 2/4, 2013 at 14:9 Comment(0)
C
2

If a library is a possibility, Chance.js might be of help: http://chancejs.com/#string

Chryso answered 15/4, 2014 at 16:29 Comment(0)
B
2

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.

Baste answered 1/6, 2018 at 7:30 Comment(0)
B
2

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

Bartolommeo answered 19/9, 2018 at 18:31 Comment(0)
H
2

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.
Heinrich answered 20/11, 2018 at 8:58 Comment(0)
G
2

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);
General answered 29/1, 2019 at 12:48 Comment(0)
M
2

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);
Mandate answered 19/5, 2020 at 6:23 Comment(0)
G
2

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;
Galegalea answered 20/10, 2021 at 18:25 Comment(0)
H
1
",,,,,".replace(/,/g,function (){return "AzByC0xDwEv9FuGt8HsIrJ7qKpLo6MnNmO5lPkQj4RiShT3gUfVe2WdXcY1bZa".charAt(Math.floor(Math.random()*62))});
Hord answered 28/8, 2009 at 21:14 Comment(1)
too much regex. Too slow.Locative
I
1

This stores 5 alphanumeric characters in variable c.

for(var c = ''; c.length < 5;) c += Math.random().toString(36).substr(2, 1)
Illusionist answered 30/6, 2014 at 18:54 Comment(0)
F
1

I loved the brievety of doubletap's Math.random().toString(36).substring(7) answer, but not that it had so many collisions as hacklikecrack correctly pointed out. It generated 11-chacter strings but has a duplicate rate of 11% in a sample size of 1 million.

Here's a longer (but still short) and slower alternative that had only 133 duplicates in a sample space of 1 million. In rare cases the string will still be shorter than 11 chars:

Math.abs(Math.random().toString().split('')
    .reduce(function(p,c){return (p<<5)-p+c})).toString(36).substr(0,11);
Featherweight answered 5/11, 2014 at 22:31 Comment(0)
M
1

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 )
Measureless answered 8/1, 2015 at 22:52 Comment(0)
P
1

Put the characters as the thisArg in the map function will create a "one-liner":

Array.apply(null, Array(5))
.map(function(){ 
    return this[Math.floor(Math.random()*this.length)];
}, "abcdefghijklmnopqrstuvwxyz")
.join('');
Processional answered 23/11, 2015 at 13:28 Comment(0)
M
1

Random numeric value (up to 16 digits)

/**
 * Random numeric value (up to 16 digits)
 * @returns {String}
 */
function randomUid () {
  return String(Math.floor(Math.random() * 9e15))
}

// randomUid() -> "3676724552601324"
Maddalena answered 28/7, 2017 at 11:18 Comment(0)
G
1

Here is a different approach with fixed length by base, without RegExp replace lack (based on @bendytree's answer);

function rand(base) {
    // default base 10
    base = (base >= 2 && base <= 36) ? base : 10;
    for (var i = 0, ret = []; i < base; i++) {
        ret[i] = ((Math.random() * base) | 0).toString(base)
            // include 0-9a-zA-Z?
            // [Math.random() < .5 ? 'toString' : 'toUpperCase']();
    }
    return ret.join('');
}
Gradation answered 13/9, 2017 at 19:46 Comment(0)
H
1

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.

Heliocentric answered 16/1, 2019 at 1:4 Comment(0)
G
1

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
Graphology answered 17/5, 2019 at 9:15 Comment(0)
R
1

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));
Rumanian answered 16/7, 2020 at 16:40 Comment(0)
P
1
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)
}
Phonolite answered 8/8, 2020 at 23:50 Comment(0)
H
1
[..."abcdefghijklmnopqrsuvwxyz0123456789"].map((e, i, a) => a[Math.floor(Math.random() * a.length)]).join('')
Hump answered 14/7, 2021 at 14:25 Comment(0)
C
1

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
}
Comte answered 12/11, 2021 at 13:21 Comment(0)
S
1

In one line

Array.from({ length: 5 }, i => String.fromCharCode(Math.round(Math.ceil(Math.random() * 25) + 65))).join('');
Smatter answered 15/11, 2023 at 10:5 Comment(1)
Note that this only returns uppercase lettersTervalent
T
0

Another nice way to randomize a string from the characters A-Za-z0-9:

function randomString(length) {
    if ( length <= 0 ) return "";
    var getChunk = function(){
        var i, //index iterator
            rand = Math.random()*10e16, //execute random once
            bin = rand.toString(2).substr(2,10), //random binary sequence
            lcase = (rand.toString(36)+"0000000000").substr(0,10), //lower case random string
            ucase = lcase.toUpperCase(), //upper case random string
            a = [lcase,ucase], //position them in an array in index 0 and 1
            str = ""; //the chunk string
        b = rand.toString(2).substr(2,10);
        for ( i=0; i<10; i++ )
            str += a[bin[i]][i]; //gets the next character, depends on the bit in the same position as the character - that way it will decide what case to put next
        return str;
    },
    str = ""; //the result string
    while ( str.length < length  )
        str += getChunk();
    str = str.substr(0,length);
    return str;
}
Tedmann answered 31/10, 2013 at 16:21 Comment(0)
F
0

The npm module anyid provides flexible API to generate various kinds of string ID / code.

const id = anyid().encode('Aa0').length(5).random().id();
Frigorific answered 5/8, 2016 at 5:27 Comment(0)
H
0

In below code I am generating random code for 8 characters

function RandomUnique(){
                    var charBank = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
                    var random= '';
                    var howmanycharacters = 8;
                    for (var i = 0; i < howmanycharacters ; i++) {
                        random+= charBank[parseInt(Math.random() * charBank.lenght)];
                    }
                    return random;
                }
        var random = RandomUnique();
        console.log(random);
Harmonica answered 21/6, 2017 at 7:32 Comment(0)
A
0

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>
Alienism answered 24/6, 2017 at 10:29 Comment(0)
E
0

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?

Expanded answered 3/10, 2017 at 2:58 Comment(4)
Omg... maintaining this code would be a pain. Too hacky and not readable. Always write code for humans, that can eventually be executed by a machine, not the opposite. And all this unnecessary micro-optimization is pure evil... CPU cycles are cheap. It really doesn't matter if pushing to an array is faster than concatenating or if the cryptic double tilde is faster than Math.floor.Antechamber
This is all opinion based. This code has been running flawlessly since I wrote it for this answer. I use it in a distributed system that broadcasts updates and generates thousands of unique IDs per minute, during high throughput. The ease of un-commenting a line to add characters is so simple. I don't see much room for programmers in your philosophy of "Don't to it if it doesn't need to be done".Expanded
I dont know. All humans want to program and forget that there is a machine in front of them. in the 80s it was good to know math for programming. Today its a nice to have? Is it really a big deal to read a chained condition? No! Not for me! Well language is important. but speaking functions and symbols are for me a nice to have. combine of both worlds and you are a skilled programmer! I cannot believe the downvote. this is not stack overflowWorldly
You misunderstood me @Duco. I don't preach "Don't to it if it doesn't need to be done". I don't know from where you concluded that, once I never said something like this. Actually, I'm very often criticized of reinventing the wheel and I'm proud of it! Avoiding libraries and doing it ourselves is good... sometimes! There's a limit. Math.floor is part of the core, for example. My main complain here is that the code is hacky and hard to read. BTW, commented code to be used later is also bad practice. Make your function take another parameter if you want to control its behavior.Antechamber
G
0

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');
Gwalior answered 21/11, 2017 at 10:36 Comment(1)
Generally it is considered bad practice to extend native objects (you might release Cthulhu). See - stackoverflow.com/questions/14034180/…Lamasery
D
0

You could use base64:

function randomString(length)
{
    var rtn = "";

    do {
        rtn += btoa("" + Math.floor(Math.random() * 100000)).substring(0, length);
    }
    while(rtn.length < length);

    return rtn;
}
Dinky answered 8/4, 2018 at 8:53 Comment(0)
B
0

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") 
Bateau answered 16/8, 2018 at 22:7 Comment(0)
Q
0

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.

Queensland answered 1/2, 2020 at 5:59 Comment(0)
T
0

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

Tessietessier answered 21/6, 2020 at 21:36 Comment(0)
C
0

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

Clorindaclorinde answered 1/7, 2020 at 17:51 Comment(0)
S
0

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))
Sparke answered 4/7, 2020 at 6:53 Comment(0)
C
0

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.

Commorancy answered 1/6, 2021 at 18:32 Comment(0)
I
0

You can use Web Crypto's API:

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

(original answer here)

Incapable answered 29/7, 2022 at 16:23 Comment(1)
This only generates random numeric strings.Acevedo
F
0
function generateRandomStringLettersAndNumbers(maxLength): string {
  return crypto.randomBytes(maxLength).toString('hex').substring(0, maxLength);
}
Follmer answered 16/1, 2023 at 18:51 Comment(0)
L
0

A reduced random alphanumeric with upper and lowercase:

const l = 98 // length

// Node
Array.from(crypto.randomBytes(l)).reduce((s, b) => s + (b % 35).toString(36)[(b % 2) - 1 ? '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 % 35).toString(36)[(b % 2) - 1 ? 'toLowerCase' : 'toUpperCase'](), '')
Longo answered 14/12, 2023 at 19:8 Comment(0)
A
-1

I use var randId = 'rand' + new Date().getTime();

Attending answered 29/3, 2017 at 21:31 Comment(8)
That's the opposite of random. If you need randomized IDs and generate multiple IDs in, say, a for-loop using this method, you'll probably get some identical IDs. Further, users can influence your ID choice by setting their computer's date/time. That's not something you likely want to do.Foozle
it really depends for what you need it in my case i needed to add id to line when user adds row and you cant click twice in 1 ms,Attending
You can, however, double click just as some background process or other piece of JavaScript code hangs the browser for a few milliseconds, which causes the next two click events to be handled within the 'same' millisecond. It's unlikely it will happen, sure, but it's not impossible. Therefore the code is unpredictable. Especially if you cant guarentee running time and such on all devices your website/app will be running on.Foozle
i would like to see a demo of that, in my opinion that's not possible, unless you click with a bot 🤖Attending
Here you go: gist.github.com/JochemKuijpers/86217cec7c860c0af0dfc06bbddacc42 I managed to get a few identical IDs on Chrome (easily reproducible on my 6th gen i5 machine). I can imagine this is even more an issue on mobile browsers with less accurate timers.Foozle
thanks thats if you generate multiple ids after 1 click event, i needed to add to a table "1" row and needed unique id and there was no way that user can click it so fast, but if you have loop then sure i would never use such a thingAttending
No, those are multiple click events behind handled sequentially within the same millisecond. They are queued up because some other code is hanging the browser. JavaScript does not have concurrent code execution (at least; not for click events), so the browser has to wait for the stalling bit of code to finish before it can handle the click events. Anyway, well, if it works for you, go ahead. Just know the risks that a slow computer or a computer with an inaccurate timer might generate identical IDs.Foozle
got you, yes you need to know the case,Attending
I
-1

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
Insessorial answered 22/4, 2019 at 12:57 Comment(3)
Date.now() most certainly does not produce thirteen "random" digitsAnam
@Molomby, brother, I appreciate your time but please write the logic in which case it will not produce thirteen "random" digits.Insessorial
Randomness is the lack of predictability. The digits produced by Date.now() represent the current date/time of the machine on which the function is called. They are highly predictable and simply not "random" by any stretch of the definition. True randomness is hard; even Math.random() isn't truly random, it's pseudorandom. You'll see other answers in this thread recommending the crypto module which is better (but still not truly random). Start here for more info: developer.mozilla.org/en-US/docs/Glossary/RNGAnam
G
-1

//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)
Graphemics answered 25/4, 2020 at 17:26 Comment(2)
This is just one of the top answers with very minor modifications.Tardy
i just tried making it more easier and readable.Graphemics
D
-1

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);
Dibbuk answered 30/12, 2020 at 21:40 Comment(0)
C
-1

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://mcmap.net/q/20795/-i-have-to-hash-a-text-with-hmac-sha256-in-javascript

Capsule answered 26/3, 2022 at 19:23 Comment(0)
D
-2

Here is an example in CoffeeScript:

String::add_Random_Letters   = (size )->
                                         charSet = 'abcdefghijklmnopqrstuvwxyz'
                                         @ + (charSet[Math.floor(Math.random() * charSet.length)]  for i in [1..size]).join('')

which can be used

value = "abc_"
value_with_exta_5_random_letters = value.add_Random_Letters(5)
Dijon answered 31/10, 2014 at 20:19 Comment(0)
C
-3

Here's Coffeescript version one line of code

genRandomString = (length,set) -> [0...length].map( -> set.charAt Math.floor(Math.random() * set.length)).join('')

Usage:

genRandomString 5, 'ABCDEFTGHIJKLMNOPQRSTUVWXYZ'

Output:

'FHOOV' # random string of length 5 in possible set A~Z
Characterization answered 1/7, 2016 at 9:50 Comment(0)
S
-3

//To return a random letter

let alpha = "ABCDEFGHIGKLMNOPQRSTUVWXYZ";
console.log(alpha.charAt(Math.floor(Math.random() * alpha.length)));
Sunset answered 11/5, 2022 at 12:13 Comment(1)
Please avoid posting solutions that already exists.Shane

© 2022 - 2024 — McMap. All rights reserved.