我想要一个5个字符的字符串,由从集合[a-zA-Z0-9]中随机选取的字符组成。

用JavaScript实现这一点的最佳方法是什么?


当前回答

像这样的东西应该有用

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;
}

使用默认字符集[a-zA-Z0-9]调用或发送您自己的:

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');

其他回答

通过回答Gertas和Dragon提出的问题,扩展Doubletap的优雅示例。只需添加一个while循环来测试那些罕见的空情况,并将字符限制为五个。

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;
}

这里有一个jsfiddle提示您一个结果:http://jsfiddle.net/pLJJ7/

改进了上面@Andrew的回答:

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

随机数的基数36转换是不一致的,因此选择一个标记可以解决这个问题。您可以使用所需的确切长度更改字符串的长度。

我喜欢doubletap的Math.random().toString(36).substring(7)答案的简洁,但并不是因为它有很多像hack-likecrack正确指出的冲突。它生成了11个字符字符串,但在100万个样本中,重复率为11%。

这里有一个更长(但仍然很短)、更慢的替代方案,在100万个样本空间中只有133个副本。在极少数情况下,字符串仍将短于11个字符:

Math.abs(Math.random().toString().split('')
    .reduce(function(p,c){return (p<<5)-p+c})).toString(36).substr(0,11);

如果您使用的是Lodash或Undercore,那么非常简单:

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

最紧凑的解决方案,因为切片比子字符串短。从字符串末尾减去允许避免由随机函数生成的浮点符号:

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

甚至

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

更新:添加了一种使用btoa方法的方法:

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

//使用Math.random和Base 36:console.log(Math.random().toString(36).slice(-5));//使用新的日期和基数36:console.log((+new Date).toString(36).slice(-5));//使用Math.random和Base 64(btoa):console.log(btoa(Math.random()).slice(0,5));//使用新的日期和基数64(btoa):console.log(btoa(+新日期).slice(-7,-2));console.log(btoa(+新日期).substr(-7,5));