在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个回答

4
这篇文章结合了许多给出的答案。

var randNo = Math.floor(Math.random() * 100) + 2 + "" + new Date().getTime() +  Math.floor(Math.random() * 100) + 2 + (Math.random().toString(36).replace(/[^a-zA-Z]+/g, '').substr(0, 5));

console.log(randNo);

我已经使用了1个月,效果非常好。

4
这个怎么样:Date.now().toString(36)?它不算是非常随机,但每次调用都会生成一个短小且相当独特的值。

1
很遗憾,这并不是唯一的,因为 Date.now() 只有毫秒分辨率。例如在简单的循环中运行时,你会得到很多重复的值。 for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); } - Nate

4

如果你在开发Node.js应用程序,建议使用crypto模块。以下是实现randomStr()函数的示例。

const crypto = require('crypto');
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(crypto.randomInt(charset.length)))
    .join('');

如果你不是在服务器环境中工作,只需替换随机数生成器:

const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(Math.floor(Math.random() * charset.length)))
    .join('');

4

这是我使用的代码。结合了几个方法。我在一个循环中使用它,每个生成的ID都是唯一的。它可能不是5个字符,但是保证唯一性。

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

1
值得一提的是,这并不是“保证”唯一,只是非常可能唯一。请考虑 Math.random() 可能会返回两次零。此外,如果两个不同的 36 进制数被输入到 .replace(/[^a-z]+/g, ''); 中具有相同的非数字字符序列(例如 abc1 和 abc2),它们将返回相同的ID。 - Milosz

4
这里是第一答案的测试脚本(感谢@csharptest.net)。脚本运行了100万次makeid(),你可以看到5并不是非常独特的数字。使用10个字符长度运行它是相当可靠的。我已经运行了大约50次,并没有看到重复的情况:-)
注意:节点堆栈大小限制在大约400万左右,所以你不能运行500万次,否则永远无法完成。
function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

ids ={}
count = 0
for (var i = 0; i < 1000000; i++) {
    tempId = makeid();
    if (typeof ids[tempId] !== 'undefined') {
        ids[tempId]++;
        if (ids[tempId] === 2) {
            count ++;
        }
        count++;
    }else{
        ids[tempId] = 1;
    }
}
console.log("there are "+count+ ' duplicate ids');

4
你可以使用coderain。它是一个根据给定模式生成随机码的库。使用#作为大写和小写字符以及数字的占位符:
var cr = new CodeRain("#####");
console.log(cr.next());

除了占位符X之外,其他常用的占位符还有大写字母A和数字9

值得注意的是,调用.next()方法总会给你一个唯一的结果,因此您不必担心重复。

这里有一个演示应用程序,它生成一系列独特的随机代码

完全透明:我是coderain的作者。


请勿使用本地方法。 - user285594

3

在Doubletap的优雅示例基础上,回答Gertas和Dragon提出的问题。只需添加一个while循环以测试这些罕见的null情况,并将字符限制为五个。

function rndStr() {
    x=Math.random().toString(36).substring(7).substr(0,5);
    while (x.length!=5){
        x=Math.random().toString(36).substring(7).substr(0,5);
    }
    return x;
}

这里是一个 JSFiddle 的提示框,显示了一个结果:http://jsfiddle.net/pLJJ7/

2

对于包含大写字母、小写字母和数字(0-9a-zA-Z)的字符串,以下版本可能是最优的代码压缩版本:

function makeId(length) {
  var id = '';
  var rdm62;
  while (length--) {
   // Generate random integer between 0 and 61, 0|x works for Math.floor(x) in this case 
   rdm62 = 0 | Math.random() * 62; 
   // Map to ascii codes: 0-9 to 48-57 (0-9), 10-35 to 65-90 (A-Z), 36-61 to 97-122 (a-z)
   id += String.fromCharCode(rdm62 + (rdm62 < 10 ? 48 : rdm62 < 36 ? 55 : 61)) 
  }
  return id;
}

这个函数的内容可以压缩到97个字节,而最佳答案需要149个字节(因为字符列表)。

2

2

为了保存纪念,请发布一个符合ES6标准的版本。如果这个代码被频繁调用,请确保将.length值存储在常量变量中。

// USAGE:
//      RandomString(5);
//      RandomString(5, 'all');
//      RandomString(5, 'characters', '0123456789');
const RandomString = (length, style = 'frictionless', characters = '') => {
    const Styles = {
        'all':          allCharacters,
        'frictionless': frictionless,
        'characters':   provided
    }

    let result              = '';
    const allCharacters     = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const frictionless      = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    const provided          = characters;

    const generate = (set) => {
        return set.charAt(Math.floor(Math.random() * set.length));
    };

    for ( let i = 0; i < length; i++ ) {
        switch(Styles[style]) {
            case Styles.all:
                result += generate(allCharacters);
                break;
            case Styles.frictionless:
                result += generate(frictionless);
                break;
            case Styles.characters:
                result += generate(provided);
                break;
        }
    }
    return result;
}

export default RandomString;

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