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

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


当前回答

以下代码将使用npm包加密随机字符串生成大小为[a-zA-Z0-9]的加密安全随机字符串。使用以下方法安装:

npm install crypto-random-string

要在集合[a-zA-Z0-9]中获得30个字符的随机字符串:

const cryptoRandomString = require('crypto-random-string');
cryptoRandomString({length: 100, type: 'base64'}).replace(/[/+=]/g,'').substr(-30);

摘要:我们正在替换一个大的随机base64字符串中的/,+,=,并获取最后N个字符。

PS:在子字符串中使用-N

其他回答

递归解决方案:

function generateRamdomId (seedStr) {
const len = seedStr.length
console.log('possibleStr', seedStr , ' len ', len)
if(len <= 1){
    return seedStr
}
const randomValidIndex  = Math.floor(Math.random() * len)
const randomChar = seedStr[randomValidIndex]
const chunk1 = seedStr.slice(0, randomValidIndex)
const chunk2 = seedStr.slice(randomValidIndex +1)
const possibleStrWithoutRandomChar = chunk1.concat(chunk2)

return randomChar + generateRamdomId(possibleStrWithoutRandomChar)

}

你可以用你想要的种子,如果你不想,不要重复字符。实例

generateRandomId("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") 

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

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

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

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

这个小巧的小把戏怎么样?

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var stringLength = 5;

function pickRandom() {
    return possible[Math.floor(Math.random() * possible.length)];
}

var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

您需要Array.apply来将空数组变为未定义的数组。

如果您正在为ES2015进行编码,那么构建阵列会简单一些:

var randomString = Array.from({ length: stringLength }, pickRandom).join('');

非常简单

function getRandomColor(){
  var color='';
  while(color.length<6){
    color=Math.floor(Math.random()*16777215).toString(16);
  }
  return '#'+color;
}
",,,,,".replace(/,/g,function (){return "AzByC0xDwEv9FuGt8HsIrJ7qKpLo6MnNmO5lPkQj4RiShT3gUfVe2WdXcY1bZa".charAt(Math.floor(Math.random()*62))});