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

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


当前回答

您可以使用Web Crypto的API:

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

(此处为原始答案)

其他回答

喜欢这个SO问题和他们的答案。因此,提出了更具创意的解决方案。我提出了一个封装在函数中的函数,该函数接收要获取的字符串的长度加上一个模式参数,以决定如何编写字符串。

模式是一个3长度的字符串,只接受“1s”和“0s”,它们定义了要在最终字符串中包含的字符子集。它由3个不同的子集([0-9]、[A-B]、[A-B])分组

'100': [0-9]
'010': [A-B]
'101': [0-9] + [a-b]
'111': [0-9] + [A-B] + [a-b]

有8种可能的组合(2^N,其中N:#子集)。“000”模式返回空字符串。

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)]]), '')
}

一个简单的用例是:

random = randomStr(50, '101')
// ii3deu9i4jk6dp4gx43g3059vss9uf7w239jl4itv0cth5tj3e
// Will give you a String[50] composed of [0-9] && [a-b] chars only.

这里的主要思想是使用UNICODE表,而不是像我在许多答案中看到的那样随机化十六进制。这种方法的强大之处在于,您可以很容易地将其扩展为包含UNICODE表的其他子集,其中包含一些随机int(16)无法完成的额外代码。

为了满足要求[a-zA-Z0-9]和5个字符的长度,使用

对于浏览器:

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

对于NodeJS:

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

将出现小写字母、大写字母和数字。

(字体兼容)

生成包含aA zZ和0-9字符集合的随机字符串。只需使用长度参数调用此函数。

所以要回答这个问题: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
}

生成不带数字的字符串的版本:

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

这是最干净的了。它也很快,http://jsperf.com/ay-random-string.

最简单的方法是:

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

这将基于当前时间生成5个字符的随机字符串。示例输出为4mtxj或4mv90或4mwp1

这样做的问题是,如果您在同一秒内调用它两次,它将生成相同的字符串。

更安全的方法是:

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

这将生成一个4或5个字符的随机字符串,总是不同的。示例输出类似于30jzm或1r591或4su1a

在这两种方式中,第一部分生成一个随机数。.toString(36)部分将数字转换为它的base36(字母十进制)表示形式。