协慌网

登录 贡献 社区

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

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

使用 JavaScript 执行此操作的最佳方法是什么?

答案

let r = Math.random().toString(36).substring(7);
console.log("random", r);

注意:上述算法有以下缺点:

  • 它将生成 0 到 6 个字符之间的任何位置,因为在对浮点进行字符串化时会删除尾随零。
  • 它很大程度上取决于用于字符串化浮点数的算法,这种算法非常复杂。 (参见文章“如何准确打印浮点数” 。)
  • Math.random()可能会产生可预测的(“随机的” 但不是真正随机的)输出,具体取决于实现。当您需要保证唯一性或不可预测性时,生成的字符串不适合。
  • 即使它产生了 6 个均匀随机,不可预测的字符,由于生日悖论 ,你可能会在生成大约 50,000 个字符串之后看到重复。 (sqrt(36 ^ 6)= 46656)

我认为这对你有用:

function makeid(length) {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

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

  return text;
}

console.log(makeid(5));

Math.random对这种事情不好

选项 1

如果您能够在服务器端执行此操作,只需使用加密模块即可

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

结果字符串的长度是您生成的随机字节的两倍; 编码为十六进制的每个字节为 2 个字符。 20 个字节将是 40 个十六进制字符。


选项 2

如果你必须做这个客户端 ,也许尝试 uuid 模块

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

选项 3

如果你必须在客户端做这个并且你不必支持旧的浏览器,你可以做到没有依赖

// dec2hex :: Integer -> String
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"