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

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


当前回答

以下是CoffeeScript中的示例:

String::add_Random_Letters   = (size )->
                                         charSet = 'abcdefghijklmnopqrstuvwxyz'
                                         @ + (charSet[Math.floor(Math.random() * charSet.length)]  for i in [1..size]).join('')

可以使用

value = "abc_"
value_with_exta_5_random_letters = value.add_Random_Letters(5)

其他回答

这是我用过的。这是一对夫妇的组合。我在循环中使用它,它生成的每个ID都是唯一的。它可能不是5个字符,但它保证是唯一的。

var newId =
    "randomid_" +
    (Math.random() / +new Date()).toString(36).replace(/[^a-z]+/g, '');

回顾

许多答案基于技巧Math.random().toString(36),但这种方法的问题是Math.randum并不总是产生以36为基数至少有5个字符的数字。

让testRnd=n=>console.log(`num dec:${n},num base36:${n.toString(36)},string:${n.toString(36,substr(2,5)}`);[Math.random(),//并且远小于0.5。。。0.5,0.50077160493827161,0.5015432098765432,0.5023148148148148,0.5030864197530864,//还有更多。。。。0.9799597050754459].map(n=>测试Rnd(n));console.log('…等等');以下每个示例(第一个除外)的数字结果少于5个字符(不符合OP问题要求)

这里是“生成器”,允许手动查找这些数字

函数base36Todec(十六进制){hex=十六进制拆分(/\./);return(parseInt(hex[1],36))*(36**-hex[1].length)++(parseInt(hex[0],36);}函数calc(十六进制){设dec=base36Todec(十六进制);msg.innerHTML=`dec:<b>${dec}</b><br>十六进制测试:<b>${dec.toString(36)}</b>`} 函数calc2(dec){msg2.innerHTML=`dec:<b>${dec}</b><br>十六进制测试:<b>${(+dec).toString(36)}</b>`} 让init=“0.za1”;inp.value=init;calc(初始化);键入0-1范围内的数字,使用基数36(0-9,a-z),点后少于5位<br><input-oninput=“calc(this.value)”id=“inp”/><div id=“msg”></div><br>如果上面的<i>十六进制测试</i>在点后给出的数字多于5,那么您可以尝试将dec数字复制到下面的字段,并将一些数字连接到dec数字右侧和/或更改最后一个数字-它有时也会产生数字较少的十六进制<br><input-oninput=“calc2(this.value)”/><br><div id=“msg2”></div>

我已经在这里给出了答案,所以我不会在这里提出另一个解决方案

递归解决方案:

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 generateRandomStringLettersAndNumbers(maxLength): string {
  return crypto.randomBytes(maxLength).toString('hex').substring(0, maxLength);
}

教人钓鱼:

程序员用激光切割纸张,而不是电锯。使用边缘的、特定于语言的方法来生成最小、最模糊的代码是非常可爱的,但永远不会提供完整的解决方案。你必须使用合适的工具来完成这项工作。

您需要的是字符串,字符由字节表示。而且,我们可以用数字在JavaScript中表示一个字节。因此,我们应该生成这些数字的列表,并将它们转换为字符串。你不需要Date或base64;Math.random()将获得一个数字,String.fromCharCode()将其转换为字符串。容易的

但是,哪个数字等于哪个字符?UTF-8是web上用于将字节解释为字符的主要标准(尽管JavaScript内部使用UTF-16,但它们是重叠的)。程序员解决这个问题的方法是查看文档。

UTF-8以0到128之间的数字列出键盘上的所有键。有些是非打印的。只需在随机字符串中选择所需的字符,然后使用随机生成的数字搜索它们。

Bellow是一个几乎无限长的函数,在循环中生成一个随机数,并搜索低128位UTF-8代码中的所有打印字符。熵是固有的,因为并非所有随机数每次都会命中(非打印字符、空格等)。当您添加更多字符时,它的执行速度也会更快。

我已经包含了线程中讨论的大多数优化:

双颚化符比Math.floor快“if”语句比正则表达式更快推送到数组比字符串串联更快

函数randomID(len){var字符;var arr=[];var len=长度||5;做{char=~~(Math.random()*128);如果(((字符>47和字符<58)| |//0-9(字符>64和字符<91)||//A-Z(字符>96和字符<123)//a-z//||(字符>32&&字符<48)//!"#$%&,()*+'-.///|(字符>59&&字符<65)//<=>@//|(字符>90&&字符<97)//[\]^_`//|(字符>123&&字符<127)//{|}~)//安全意识删除:“'\`//&&(char!=34&&char!=39&&char!=92&&char!=96)){arr.push(String.fromCharCode(char))}}而(arr.length<len);return arr.join(“”)}var input=document.getElementById('length');input.onfocus=函数(){input.value=“”;}document.getElementById('button').onclick=函数(){var view=document.getElementById(“字符串”);var is_number=str=>!编号.isNaN(parseInt(str));if(is_number(input.value))view.innerText=随机ID(input.value);其他的view.innerText='输入数字';}#长度,长度{宽度:3em;颜色:#484848;}#字符串{颜色:#E83838;字体系列:'sans-serif';换行:换行;}<input id=“length”type=“text”value=“#”/><input id=“button”type=“button“value=“Generate”/><p id=“string”></p>

为什么要用这种乏味的方式?因为你可以。你是个程序员。你可以让电脑做任何事情!此外,如果你想要一串希伯来语字符呢?这并不难。在UTF-8标准中查找这些字符并搜索它们。将自己从这些McDonald方法中解放出来,比如toString(36)。

有时,创建真正的解决方案需要降低抽象级别。了解手头的基本原理可以让您按照自己的意愿定制代码。也许你想要一个无限生成的字符串来填充一个循环缓冲区?也许你希望所有生成的字符串都是回文?为什么要克制自己?