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

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


当前回答

这里有一种不同的方法,按基数固定长度,不使用RegExp替换lack(基于@bendytree的答案);

function rand(base) {
    // default base 10
    base = (base >= 2 && base <= 36) ? base : 10;
    for (var i = 0, ret = []; i < base; i++) {
        ret[i] = ((Math.random() * base) | 0).toString(base)
            // include 0-9a-zA-Z?
            // [Math.random() < .5 ? 'toString' : 'toUpperCase']();
    }
    return ret.join('');
}

其他回答

没有最好的方法可以做到这一点。只要结果符合您的要求,您可以选择任何方式。为了说明,我创建了许多不同的示例,所有这些示例都应该提供相同的最终结果

本页上的大多数其他答案忽略了大写字符要求。

这是我最快、最易读的解决方案。它基本上与公认的解决方案相同,只是速度稍快。

function readableRandomStringMaker(length) {
  for (var s=''; s.length < length; s += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.charAt(Math.random()*62|0));
  return s;
}
console.log(readableRandomStringMaker(length));
// e3cbN

这是一个紧凑的递归版本,可读性差得多:

const compactRandomStringMaker = (length) => length-- && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) + (compactRandomStringMaker(length)||"");
console.log(compactRandomStringMaker(5));
// DVudj

更紧凑的单层衬里:

Array(5).fill().map(()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62)).join("")
// 12oEZ

上述内容的变体:

"     ".replaceAll(" ",()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62))

最紧凑的一行程序,但效率低且不可读-它添加随机字符并删除非法字符,直到长度为l:

((l,f=(p='')=>p.length<l?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())(5)

一个加密安全的版本,这是为了紧凑而浪费熵,并且是一种浪费,因为生成的字符串很短:

[...crypto.getRandomValues(new Uint8Array(999))].map((c)=>String.fromCharCode(c).replace(/[^a-z0-9]/i,'')).join("").substr(0,5)
// 8fzPq

或者,如果没有长度参数,它甚至更短:

((f=(p='')=>p.length<5?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())()
// EV6c9

然后更具挑战性——使用无名递归箭头函数:

((l,s=((l)=>l--&&"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0)+(s(l)||""))) => s(l))(5);
// qzal4

这是一个“神奇”变量,每次访问它时都会提供一个随机字符:

const c = new class { [Symbol.toPrimitive]() { return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) } };
console.log(c+c+c+c+c);
// AgMnz

上述更简单的变体:

const c=()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0);
c()+c()+c()+c()+c();
// 6Qadw

这样怎么样:Date.now().toString(36)不是很随意,但每次调用它时都很短且非常独特。

为了从一个数组中生成一个散列作为一个盐,[0,1,2,3]在这个例子中,通过这种方式,我们可以稍后检索散列来填充一个条件。

只需输入一个随机数组,或作为数组的额外安全和快速指纹。

/*该方法非常快速,适用于密集循环*//*返回大小写混合字符*//*这将始终输出相同的哈希,因为salt数组是相同的*/控制台日志(btoa(String.fromCharCode(…新Uint8Array([0,1,2,3])))/*始终输出此处的随机十六进制哈希:30个字符*/控制台日志(btoa(String.fromCharCode(…new Uint8Array(Array(30).fill().map(()=>Math.round(Math.random()*30)))))

使用加密API中的HMAC,了解更多信息:https://stackoverflow.com/a/56416039/2494754

const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

随机unicode字符串

此方法将返回一个随机字符串,其中包含任何受支持的unicode字符,这不是OP要求的100%,而是我想要的:

function randomUnicodeString(length){
    return Array.from({length: length}, ()=>{
        return String.fromCharCode(Math.floor(Math.random() * (65536)))
    }).join('')
}

根本原因

这是谷歌搜索“随机字符串javascript”时的最高结果,但OP只要求a-zA-Z0-9。