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

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


当前回答

Math.random不适合这种情况

服务器端

使用节点加密模块-

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

// "bb5dc8842ca31d4603d6aa11448d1654"

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


客户端

使用浏览器的加密模块crypto.getRandomValues-

通过crypto.getRandomValues()方法,可以获得加密的强随机值。作为参数给出的数组用随机数填充(在其密码意义上是随机的)。

//dec2hex::整数->字符串//即0-255->“00”-“f”功能dec2hex(dec){return dec.toString(16).padStart(2,“0”)}//generateId::整数->字符串函数生成器ID(len){var arr=新Uint8Array((len||40)/2)window.crypto.getRandomValues(arr)return Array.from(arr,dec2hex).join(“”)}console.log(generateId())//“82defcf324571e70b0521d79cce2bf3ffccd69”console.log(generateId(20))//“c1a050a4cd1556948d41”

分步控制台示例-

> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]

> window.crypto
Crypto { subtle: SubtleCrypto }

> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed

> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]

对于IE11支持,您可以使用-

(window.crypto || window.msCrypto).getRandomValues(arr)

有关浏览器覆盖范围,请参阅https://caniuse.com/#feat=getrandomvalues


客户端(旧浏览器)

如果您必须支持旧浏览器,请考虑像uuid这样的东西-

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

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

其他回答

我只需要编写一个简单的包来生成具有给定大小、种子和掩码的随机令牌。仅供参考。

@sibevin/随机令牌-https://www.npmjs.com/package/@sibevin/随机令牌

import { RandomToken } from '@sibevin/random-token'

RandomToken.gen({ length: 32 })
// JxpwdIA37LlHan4otl55PZYyyZrEdsQT

RandomToken.gen({ length: 32, seed: 'alphabet' })
// NbbtqjmHWJGdibjoesgomGHulEJKnwcI

RandomToken.gen({ length: 32, seed: 'number' })
// 33541506785847193366752025692500

RandomToken.gen({ length: 32, seed: 'oct' })
// 76032641643460774414624667410327

RandomToken.gen({ length: 32, seed: 'hex' })
// 07dc6320bf1c03811df7339dbf2c82c3

RandomToken.gen({ length: 32, seed: 'abc' })
// bcabcbbcaaabcccabaabcacbcbbabbac

RandomToken.gen({ length: 32, mask: '123abcABC' })
// vhZp88dKzRZGxfQHqfx7DOL8jKTkWUuO

我已经制作了一个字符串原型,它可以生成一个给定长度的随机字符串。

如果你想要特殊字符,你也可以解密,你可以避免一些。

/**
 * 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');

希望有帮助。

仅仅一个简单的map或reduce实现就足够了:

const charset: string =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

const random1: string = [...Array(5)]
  .map((_) => charset[Math.floor(Math.random() * charset.length)])
  .join("");

const random2: string = [...Array(5)]
  .reduce<string>(
    (acc) => acc += charset[Math.floor(Math.random() * charset.length)],
    "",
  );

随机unicode字符串

此方法将返回一个随机字符串,其中包含任何受支持的unicode字符,这不是OP要求的100%,而是我想要的:

function randomUnicodeString(length){
    return Array.from({length: length}, ()=>{
        return String.fromCharCode(Math.floor(Math.random() * (65536)))
    }).join('')
}

根本原因

这是谷歌搜索“随机字符串javascript”时的最高结果,但OP只要求a-zA-Z0-9。

这样怎么样:Date.now().toString(36)不是很随意,但每次调用它时都很短且非常独特。