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

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


当前回答

这将在变量c中存储5个字母数字字符。

for(var c = ''; c.length < 5;) c += Math.random().toString(36).substr(2, 1)

其他回答

这是对doubletap优秀答案的改进。原文有两个缺点,在这里予以解决:

首先,正如其他人所提到的,它很有可能产生短字符串或甚至空字符串(如果随机数为0),这可能会破坏您的应用程序。这里有一个解决方案:

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

其次,原始和上述解决方案都将字符串大小N限制为16个字符。下面将为任何N返回大小为N的字符串(但请注意,使用N>16不会增加随机性或降低冲突概率):

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

说明:

选取[0,1)范围内的随机数,即介于0(含)和1(不含)之间。将数字转换为以36为基数的字符串,即使用字符0-9和a-z。用零填充(解决第一个问题)。去掉前导“0.”前缀和额外的填充零。重复字符串足够多次,使其中至少有N个字符(通过将空字符串与用作分隔符的较短随机字符串连接)。从字符串中精确切割N个字符。

进一步思考:

此解决方案不使用大写字母,但在几乎所有情况下(并非双关语)都无关紧要。原始答案中N=16时的最大字符串长度是用Chrome测量的。在Firefox中,N=11。但正如所解释的,第二种解决方案是关于支持任何请求的字符串长度,而不是添加随机性,因此没有太大的区别。至少在Math.random()返回的结果均匀分布的情况下,所有返回的字符串返回的概率相等(无论如何,这不是加密强度随机性)。并非所有可能的大小为N的字符串都可以返回。在第二种解决方案中,这是显而易见的(因为较小的字符串只是被复制),但在原始答案中,这也是正确的,因为在转换为base-36时,最后几位可能不是原始随机位的一部分。具体来说,如果您查看Math.random().toString(36)的结果,您会注意到最后一个字符不是均匀分布的。同样,在几乎所有的情况下,这都无关紧要,但我们从随机字符串的开头而不是结尾对最终字符串进行切片,这样短字符串(例如N=1)就不会受到影响。

更新:

下面是我想出的另外两个功能性风格的单行程序。它们与上述解决方案的不同之处在于:

他们使用一个明确的任意字母表(更通用,适用于要求大写和小写字母的原始问题)。长度为N的所有字符串返回的概率相等(即字符串不包含重复)。它们基于map函数,而不是toString(36)技巧,这使得它们更加简单易懂。

所以,说你选择的字母表是

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

那么这两个是等价的,因此您可以选择对您更直观的:

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

编辑:

我似乎认为qubyte和Martijn de Milliano提出了类似于后者的解决方案(很好!),但我不知怎么错过了。因为它们一眼看上去不那么短,所以我还是把它放在这里,以防有人真的想要一行:-)

此外,在所有解决方案中,将“new Array”替换为“Array”,以节省更多字节。

我想这会对你有用:

函数makeid(长度){let result=“”;const characters=‘EFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789’;常量字符长度=字符长度;让计数器=0;while(计数器<长度){result+=characters.charAt(Math.floor(Math.random()*charactersLength));计数器+=1;}返回结果;}console.log(makeid(5));

//创建一个长度为10的随机代码,您可以随意更改它

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)

改进了上面@Andrew的回答:

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

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

这是doubletap答案的稍微改进版本。当Math.random()返回0、0.5、0.25、0.125等时,它会考虑gertas对案例的评论。

((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)

它防止零被传递给toString,我将最小的浮点值添加到Math.random()。它确保传递给toString的数字有足够的数字,通过除以一个几乎不合理的数字。