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

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


当前回答

这不是一个完美的解决方案,但它应该奏效。如果出现任何错误,请增加Uint8Array()构造函数中给定的值。此方法的优点是它使用getRandomValues()方法生成加密的强随机值。

var array=新Uint8Array(20);crypto.getRandomValues(数组);var arrayEncoded=btoa(String.fromCharCode(…array)).split(“”);var arrayFiltered=arrayEncoded.filter(值=>{开关(值){大小写“+”:return false;大小写“/”:return false;case“=”:return false;违约:返回true;}});var password=arrayFiltered.slice(0,5).join('');console.log(密码);

紧凑型

var array=新Uint8Array(20);crypto.getRandomValues(数组);var password=btoa(String.fromCharCode(…array)).split(“”).filter(值=>{回来['+','/','=']includes(value);}).切片(0,5).连接('');console.log(密码);

其他回答

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

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

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

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

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

这不是一个完美的解决方案,但它应该奏效。如果出现任何错误,请增加Uint8Array()构造函数中给定的值。此方法的优点是它使用getRandomValues()方法生成加密的强随机值。

var array=新Uint8Array(20);crypto.getRandomValues(数组);var arrayEncoded=btoa(String.fromCharCode(…array)).split(“”);var arrayFiltered=arrayEncoded.filter(值=>{开关(值){大小写“+”:return false;大小写“/”:return false;case“=”:return false;违约:返回true;}});var password=arrayFiltered.slice(0,5).join('');console.log(密码);

紧凑型

var array=新Uint8Array(20);crypto.getRandomValues(数组);var password=btoa(String.fromCharCode(…array)).split(“”).filter(值=>{回来['+','/','=']includes(value);}).切片(0,5).连接('');console.log(密码);

像这样扩展String对象怎么样。

String.prototype.random = function(length) {
   var result = '';
   for (var i = 0; i < length; i++) {
      result += this.charAt(Math.floor(Math.random() * this.length));
   }

   return result;
};

使用它:

console.log("ABCDEFG".random(5));

随机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。