I just came across this as a really nice and elegant solution:
Math.random().toString(36).slice(2)
Notes on this implementation:
- This will produce a string anywhere between zero and 12 characters long, usually 11 characters, due to the fact that floating point stringification removes trailing zeros.
- It won't generate capital letters, only lower-case and numbers.
- Because the randomness comes from
Math.random(), the output may be predictable and therefore not necessarily unique. - Even assuming an ideal implementation, the output has at most 52 bits of entropy, which means you can expect a duplicate after around 70M strings generated.
I just came across this as a really nice and elegant solution:
Math.random().toString(36).slice(2)
Notes on this implementation:
- This will produce a string anywhere between zero and 12 characters long, usually 11 characters, due to the fact that floating point stringification removes trailing zeros.
- It won't generate capital letters, only lower-case and numbers.
- Because the randomness comes from
Math.random(), the output may be predictable and therefore not necessarily unique. - Even assuming an ideal implementation, the output has at most 52 bits of entropy, which means you can expect a duplicate after around 70M strings generated.
If you only want to allow specific characters, you could also do it like this:
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
Here's a jsfiddle to demonstrate: http://jsfiddle.net/wSQBx/
Another way to do it could be to use a special string that tells the function what types of characters to use. You could do that like this:
function randomString(length, chars) {
var mask = '';
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (chars.indexOf('#') > -1) mask += '0123456789';
if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
var result = '';
for (var i = length; i > 0; --i) result += mask[Math.floor(Math.random() * mask.length)];
return result;
}
console.log(randomString(16, 'aA'));
console.log(randomString(32, '#aA'));
console.log(randomString(64, '#A!'));
Fiddle: http://jsfiddle.net/wSQBx/2/
Alternatively, to use the base36 method as described below you could do something like this:
function randomString(length) {
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
» npm install lodash.random
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);
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('');
Short alternative using spread operator and .map()
Demo 1
const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');
console.log(genRanHex(6));
console.log(genRanHex(12));
console.log(genRanHex(3));
Pass in a number (
size) for the length of the returned string.Define an empty array (
result) and an array of strings in the range of[0-9]and[a-f](hexRef).On each iteration of a
forloop, generate a random number 0 to 15 and use it as the index of the value from the array of strings from step 2 (hexRef) -- thenpush()the value to the empty array from step 2 (result).Return the array (
result) as ajoin('')ed string.
Demo 2
const getRanHex = size => {
let result = [];
let hexRef = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
for (let n = 0; n < size; n++) {
result.push(hexRef[Math.floor(Math.random() * 16)]);
}
return result.join('');
}
console.log(getRanHex(6));
console.log(getRanHex(12));
console.log(getRanHex(3));
NodeJS Users
You can use randomBytes available in the crypto module, to generate cryptographically strong pseudorandom data of a given size. And you can easily convert it to hex.
import crypto from "crypto";
const randomString = crypto.randomBytes(8).toString("hex");
console.log(randomString) // ee48d32e6c724c4d
The above code snippet generates a random 8-bytes hex number, you can manipulate the length as you wish.