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

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


当前回答

正如这里的几个人所指出的,将Math.random()的结果直接传递给.string(36)有几个问题。

它的随机性很差。生成的字符数量各不相同,平均而言取决于Javascript中浮点数如何工作的棘手细节。如果我试图生成11个或更少的字符,但不能生成超过11个字符,这似乎是有效的。而且它不灵活。允许或禁止某些字符是不容易的。

对于任何使用lodash的人,我有一个紧凑的解决方案,它没有这些问题:

_.range(11).map(i => _.sample("abcdefghijklmnopqrstuvwxyz0123456789")).join('')

如果要允许某些字符(例如大写字母)或禁止某些字符(如l和1等不明确的字符),请修改上面的字符串。

其他回答

//可以将7更改为2以获得更长的结果。让r=(Math.random()+1).toString(36).substring(7);console.log(“随机”,r);

注:上述算法有以下缺点:

它将生成0到6个字符之间的任何字符,这是因为字符串化浮点时会删除尾随零。这在很大程度上取决于用于字符串化浮点数的算法,这非常复杂。(请参阅论文“如何准确打印浮点数字”。)根据实现的不同,Math.random()可能会产生可预测的(“看起来随机”但不是真正随机的)输出。当需要保证唯一性或不可预测性时,生成的字符串不适合。即使它产生了6个统一的随机、不可预测的字符,由于生日悖论,在只产生了大约50000个字符串之后,你也可以看到重复的字符。(平方英尺(36^6)=4656)

生成安全的随机字母数字Base-62字符串:

函数生成UID(长度){return window.btoa(String.fromCharCode(…window.crypto.getRandomValues(新Uint8Array(长度*2))).replace(/[+/]/g,“”).substring(0,长度);}console.log(生成UID(22));//“yFg3Upv2cE9cKOXd7hHwWp”console.log(生成UID(5));//“YQGzP”

我只需要编写一个简单的包来生成具有给定大小、种子和掩码的随机令牌。仅供参考。

@sibevin/随机令牌-https://www.npmjs.com/package/@sibevin/随机令牌

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

生成包含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
}

你可以使用coderain。这是一个根据给定模式生成随机代码的库。使用#作为大写和小写字符以及数字的占位符:

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

还有其他占位符,如A表示大写字母或9表示数字。

可能有用的是,调用.next()将始终为您提供唯一的结果,因此您不必担心重复。

这里是一个生成唯一随机代码列表的演示应用程序。

完全披露:我是《代码雨》的作者。