在JavaScript中生成随机字符串/字符。

2782
我希望得到一个由随机选取的字符组成的5个字符的字符串,可用字符集为[a-zA-Z0-9]
使用JavaScript,最佳方法是什么?

87
警告:所有答案都不具有“真正的随机”结果!它们只是“伪随机”。在使用随机字符串进行保护或安全时,不要使用它们中的任何一个!!!请尝试使用以下其中一种API:http://www.random.org/ - Ron van der Heijden
22
请注意:HTML5 webcrypto randomness API 提供真正的随机性。 - mikemaccana
6
如果有人在这里寻求生成一个ID或唯一标识符,让你的数据库来完成这项工作,或者使用UUID库。 - Dan
使用JavaScript、Java、Python、Rust和Bash生成随机字符串:https://fe-tool.com/zh-cn/random-password - cwtuan
试试npm库random-ext - undefined
94个回答

0

npm模块anyid提供了灵活的API来生成各种字符串ID / 代码。

const id = anyid().encode('Aa0').length(5).random().id();

0

你可以使用base64:

function randomString(length)
{
    var rtn = "";

    do {
        rtn += btoa("" + Math.floor(Math.random() * 100000)).substring(0, length);
    }
    while(rtn.length < length);

    return rtn;
}

0
在下面的代码中,我正在生成8个字符的随机代码。
function RandomUnique(){
                    var charBank = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
                    var random= '';
                    var howmanycharacters = 8;
                    for (var i = 0; i < howmanycharacters ; i++) {
                        random+= charBank[parseInt(Math.random() * charBank.lenght)];
                    }
                    return random;
                }
        var random = RandomUnique();
        console.log(random);

0

递归解决方案:

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") 

0

非常简单

function getRandomColor(){
  var color='';
  while(color.length<6){
    color=Math.floor(Math.random()*16777215).toString(16);
  }
  return '#'+color;
}

0
我已经创建了一个字符串原型,可以生成指定长度的随机字符串。您还可以指定是否需要特殊字符,并且可以避免某些字符。
/**
 * STRING PROTOTYPE RANDOM GENERATOR
 * Used to generate a random string
 * @param {Boolean} specialChars
 * @param {Number} length
 * @param {String} avoidChars
 */
String.prototype.randomGenerator = function (specialChars = false, length = 1, avoidChars = '') {
    let _pattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    _pattern += specialChars === true ? '(){}[]+-*/=' : '';
    if (avoidChars && avoidChars.length) {
        for (let char of avoidChars) {
            _pattern = _pattern.replace(char, '');
        }
    }
    let _random = '';
    for (let element of new Array(parseInt(length))) {
        _random += _pattern.charAt(Math.floor(Math.random() * _pattern.length));
    }
    return _random;
};

你可以像这样使用:

您可以这样使用:

// Generate password with specialChars which contains 10 chars and avoid iIlL chars
var password = String().randomGenerator(true, 10, 'iIlL');

希望它有所帮助。

1
通常认为扩展本机对象是一种不良做法(您可能会释放克苏鲁)。请参见-https://dev59.com/T2Yr5IYBdhLWcg3wAFg0 - Tyler Miller

0

您可以使用Web Crypto API

console.log(self.crypto.getRandomValues(new Uint32Array(1))[0])

(原始答案 在此处


这只会生成随机数字字符串。 - David Wheatley

0

教人捕鱼:

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

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

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

UTF-8将键盘上的所有键列在0到128之间的数字中。其中一些是不可打印的。只需挑选出你想要的字符,并使用随机生成的数字搜索它们即可。

以下是一个函数,它可以接受几乎无限的长度,在循环中生成随机数,并搜索所有低于128个UTF-8代码中的可打印字符。由于不所有随机数都会命中(非打印字符、空格等),因此熵是固有的。添加更多字符后,它还将执行得更快。
我已经包含了讨论中提到的大部分优化:
- 双波浪号比Math.floor更快 - “if”语句比正则表达式更快 - 将元素推入数组比字符串串联更快

function randomID(len) {
  var char;
  var arr = [];
  var len = len || 5;

  do {
    char = ~~(Math.random() * 128);

    if ((
        (char > 47 && char < 58) || // 0-9
        (char > 64 && char < 91) || // A-Z
        (char > 96 && char < 123) // a-z

        // || (char > 32 && char < 48) // !"#$%&,()*+'-./
        // || (char > 59 && char < 65) // <=>?@
        // || (char > 90 && char < 97) // [\]^_`
        // || (char > 123 && char < 127) // {|}~
      )
      //security conscious removals: " ' \ ` 
      //&& (char != 34 && char != 39 && char != 92 && char != 96) 

    ) { arr.push(String.fromCharCode(char)) }

  } while (arr.length < len);

  return arr.join('')
}

var input = document.getElementById('length');

input.onfocus = function() { input.value = ''; }

document.getElementById('button').onclick = function() {
  var view = document.getElementById('string');
  var is_number = str => ! Number.isNaN( parseInt(str));
    
  if ( is_number(input.value))
    view.innerText = randomID(input.value);
  else
    view.innerText = 'Enter a number';
}
#length {
  width: 3em;
  color: #484848;
}

#string {
  color: #E83838;
  font-family: 'sans-serif';
  word-wrap: break-word;
}
<input id="length" type="text" value='#'/>
<input id="button" type="button" value="Generate" />
<p id="string"></p>

因为你是一名程序员,所以你能够用这种繁琐的方式实现。你可以让计算机做任何事情!另外,如果你想要一串希伯来字符怎么办?这并不难。在UTF-8标准中找到这些字符并进行搜索。摆脱像toString(36)这样的麦当劳方法。
有时,降低抽象级别是创建真正解决方案所需要的。理解手头的基本原则可以让你根据自己的意愿定制代码。也许你想要一个生成无限字符串填充循环缓冲区?也许你想要所有生成的字符串都是回文?为什么要限制自己呢?

4
哎呀,维护这段代码将是一种痛苦。它太过于混乱并且难以阅读。要始终为人类编写代码,最终可以被计算机执行,而不是相反。所有这些不必要的微小优化都是纯粹的恶行...CPU周期很便宜。将元素推入数组比连接更快,或者使用晦涩的双波浪线运算符比Math.floor更快速,实际上并不重要。 - Victor Schröder
这完全是基于个人观点的。自从我为了回答问题而编写此代码以来,它一直运行得非常完美。我在一个分布式系统中使用它来广播更新并每分钟生成数千个唯一的ID,在高吞吐量期间。取消注释一行以添加字符的简单性是如此简单。我认为你的“如果不需要做就不要做”的哲学中程序员的发挥空间不大。 - Duco
我不知道。所有人都想编程,忘记了面前有一台机器。在80年代,懂数学对于编程来说是必要的;但今天,它只是一个额外的加分项?阅读链式条件真的很重要吗?不!对我而言没有问题!语言很重要,但对我来说,掌握函数和符号只是额外的加分项。同时掌握两个领域,你就是一个技艺精湛的程序员!我无法相信这样的内容会被downvote,这不是stackoverflow。 - redestructa
2
你误解了我,@Duco。我并不是在宣扬“如果不需要就不要做”的观点。我不知道你从哪里得出这个结论,因为我从来没有说过这样的话。事实上,我经常被批评重新发明轮子,但我为此感到自豪!避免使用库,自己动手做有时候是好的...但也有限制。例如,Math.floor是核心的一部分。我主要的抱怨是代码很糟糕,很难阅读。顺便说一下,注释掉的代码以后使用也是不好的习惯。如果你想控制函数的行为,请让它接受另一个参数。 - Victor Schröder

0

试试这个,这是我每次使用的:

function myFunction() {
        var hash = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
        var random8 = '';
        for(var i = 0; i < 5; i++){
            random8 += hash[parseInt(Math.random()*hash.length)];
        }
        console.log(random8);
    document.getElementById("demo").innerHTML = "Your 5 character string ===> "+random8;
}        
        
<!DOCTYPE html>
<html>
<body>

<p>Click the button to genarate 5 character random string .</p>

<button onclick="myFunction()">Click me</button>

<p id="demo"></p>



</body>
</html>


0

评价

许多答案都基于 Math.random().toString(36) 的技巧,但这种方法的问题在于 Math.random 不总是产生至少包含 5 个字符的 36 进制数字,例如。

let testRnd = n => console.log(`num dec: ${n}, num base36: ${n.toString(36)}, string: ${n.toString(36).substr(2, 5)}`);


[
  Math.random(),
  // and much more less than 0.5...
  0.5,
  0.50077160493827161,
  0.5015432098765432,
  0.5023148148148148,
  0.5030864197530864,
  // and much more....
  0.9799597050754459
].map(n=>testRnd(n));

console.log('... and so on');
Each of below example (except first) numbers result with less than 5 characters (which not meet OP question requirements)

这里有一个“生成器”,可以手动找到这样的数字。

function base36Todec(hex) {
  hex = hex.split(/\./);
  return (parseInt(hex[1],36))*(36**-hex[1].length)+ +(parseInt(hex[0],36));
}

function calc(hex) {
  let dec = base36Todec(hex);
  msg.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${dec.toString(36)}</b>`
} 

function calc2(dec) {
  msg2.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${(+dec).toString(36)}</b>`
} 

let init="0.za1";
inp.value=init;
calc(init);
Type number in range 0-1 using base 36 (0-9,a-z) with less than 5 digits after dot<br>
<input oninput="calc(this.value)" id="inp" /><div id="msg"></div>
<br>
If above <i>hex test</i> give more digits than 5 after dot - then you can try to copy dec number to below field and join some digit to dec num right side and/or change last digit - it sometimes also produce hex with less digits<br>
<input oninput="calc2(this.value)" /><br><div id="msg2"></div>

我已经在这里给出了答案,所以在这里不会再提供另外的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接