JavaScript 中的随机字母数字字符串?

IT技术 javascript random
2021-02-02 12:06:30

在 JavaScript 中生成随机字母数字(大写、小写和数字)字符串以用作可能唯一标识符的最短方法(在合理范围内)是什么?

6个回答

我刚刚发现这是一个非常好的和优雅的解决方案:

Math.random().toString(36).slice(2)

关于这个实现的注意事项:

  • 由于浮点字符串化会删除尾随零,这将生成一个长度介于 0 到 12 个字符之间的字符串,通常为 11 个字符。
  • 它不会生成大写字母,只会生成小写字母和数字。
  • 因为随机性来自Math.random(),输出可能是可预测的,因此不一定是唯一的。
  • 即使假设是一个理想的实现,输出也最多有 52 位熵,这意味着在生成大约 70M 字符串后,您可以期待重复。
2021-03-27 12:06:30
toString 接受一个基数参数,即整数被转换为字符串的“基数”。我认为最容易掌握这一点的是var a = 5;a.toString(2)将以二进制格式返回数字 5,因此101. 完整文档位于:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-01 12:06:30
你有一个繁忙的网站吗?然后有时它会生成一个小于 的随机数0.000001toString()一个较低的数字是一样的东西3.4854687E-7,你的随机字母数字字符串将是4854687E-7这不再是字母数字。不再满足 OP 的要求
2021-04-03 12:06:30
@kimos 好收获。解决这个问题的一种方法是再试一次。例如:function rStr() { var s=Math.random().toString(36).slice(2); return s.length===16 ? s : rStr(); }
2021-04-11 12:06:30
你能解释一下这是如何工作的吗?你为什么要传递36toString
2021-04-12 12:06:30

如果您只想允许特定字符,您也可以这样做:

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

这是一个 jsfiddle 来演示:http : //jsfiddle.net/wSQBx/

另一种方法是使用一个特殊的字符串来告诉函数使用什么类型的字符。你可以这样做:

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

小提琴:http : //jsfiddle.net/wSQBx/2/

或者,要使用如下所述的 base36 方法,您可以执行以下操作:

function randomString(length) {
    return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}
我冒昧地修复了代码中的统计错误。因为这是 google 上“随机 javascript 字符串”的最高结果,所以有错误的答案是一种耻辱。
2021-03-29 12:06:30
@Matthew 那可能是您的浏览器在输出字符串中无意中发现了错误标记。检查输出源,看看是否有一些任性的 < 和 > 导致问题。
2021-03-31 12:06:30
嗯,这里有一个统计错误。Math.round(Math.random() * (chars.length - 1))会给一半概率[0][chars.length-1]比字符的其余部分,以圆它们则分别需要一数目的间隔[0, 0.5)[chars.length-2+0.5, chars.length-1)尺寸0.5的,而字符的其余部分需要[index-0.5, index+0.5)尺寸1的正确的分度功能应该是:parseInt(Math.random() * chars.length)作为random() 的上限被排除在外,chars.length不会达到:w3schools.com/jsref/jsref_random.asp
2021-04-05 12:06:30
@Nimphious 请给我你的参考。Math.random()永远不会返回 1。它的返回值[0, 1)意味着 0 被包括在内,1 被排除在外。以下是四个不同且重要的独立来源: Mozilla:goo.gl/BQGZiG微软 MSDN (IE): goo.gl/MPuCJM ; w3schools: goo.gl/qXrK7P ; 计算器:goo.gl/CUoyITnum1)和goo.gl/D9az3Cgoo.gl/0mERDq您认为 1 是 Math.random() 的可能值的来源是什么?因为它不是。
2021-04-05 12:06:30
我真的很喜欢第二种方法。我尝试使用它,它似乎有一些问题。正如您在屏幕截图中所见,它有时会生成不是指定长度的字符串。我把你的randomString(..)函数放在一个for(var i=0;i<50;i++){}循环中,生成 50 个随机字符串,最后一个是三个字符长。我还告诉它像这样写文档 50 次:document.write(randomString(8, '#aA!') + "</br>");
2021-04-10 12:06:30

JAR.JAR.beans 建议的另一种答案变体

(Math.random()*1e32).toString(36)

通过更改乘数,1e32您可以更改随机字符串的长度。

我知道了!我正在寻找生成长随机字符串(接近 40 个字符)的简单解决方案
2021-03-24 12:06:30
很好的答案,这对我有帮助。使用 1e32 得到 19 个字符的长字符串,使用 1e64 得到 40 个字符。非常感谢!
2021-03-26 12:06:30
好答案 。但是,它不会生成 CAPITAL(大写)字母
2021-03-27 12:06:30
@BogdanLewis 请注意,不能保证字符串长度。意思是 1e64 并不总是产生 40 个字符长度的字符串,但它会接近 40。
2021-04-07 12:06:30

更新:单行解决方案,随机 20 个字符(字母数字小写):

Array.from(Array(20), () => Math.floor(Math.random() * 36).toString(36)).join('');

或者用 lodash 更短:

_.times(20, () => _.random(35).toString(36)).join('');

或者根据 Jar Jar 的建议,这是我在最近的一个项目中使用的(为了克服长度限制):

var randomString = function (len, bits)
{
    bits = bits || 36;
    var outStr = "", newStr;
    while (outStr.length < len)
    {
        newStr = Math.random().toString(bits).slice(2);
        outStr += newStr.slice(0, Math.min(newStr.length, (len - outStr.length)));
    }
    return outStr.toUpperCase();
};

利用:

randomString(12, 16); // 12 hexadecimal characters
randomString(200); // 200 alphanumeric characters