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

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


当前回答

快速和改进的算法。不保证统一(见注释)。

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    let result = '';

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}

其他回答

一个衬垫:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

随机字符串生成器(字母数字|字母数字|数字)

/***伪随机串发生器* http://stackoverflow.com/a/27872144/383904*默认值:返回随机字母数字字符串* *@param{Integer}len所需长度*@param{String}an可选(字母数字),“a”(字母),“n”(数字)*@return{字符串}*/函数randomString(len,an){an=an&&an.toLowerCase();var str=“”,i=0,min=an==“a”?10 : 0,max=an==“n”?10 : 62;对于(;i++<len;){var r=数学随机()*(最大值-最小值)+最小值<<0;str+=String.fromCharCode(r+=r>9?r<36?55:61:48);}返回str;}console.log(randomString(10));//即:“4Z8INGag9v”console.log(randomString(10,“a”));//即:“aUkZuHNcWw”console.log(randomString(10,“n”));//即:“9055739230”


虽然以上使用了对期望的A/N、A、N输出的附加检查,让我们将其分解为基本要素(仅限字母数字),以便更好地理解:

创建一个接受参数的函数(随机字符串结果的所需长度)创建一个空字符串,如var str=“”;连接随机字符在循环内创建一个从0到61(0..9+a.Z+a..Z=62)的rand索引编号创建一个条件逻辑来调整/修复rand(因为它是0..61),将其递增一些数字(参见下面的示例),以获取正确的CharCode编号和相关字符。在循环内部连接到str一个String.fromCharCode(递增rand)

让我们想象一下ASCII字符表范围:

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor(Math.random*62)给出了从0..61(我们需要的)的范围。让我们修复随机数以获得正确的charCode范围:

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

上表中的条件运算逻辑:

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

根据上面的解释,下面是生成的字母数字代码段:

函数randomString(len){var str=“”;//字符串结果对于(var i=0;i<len;i++){//循环“len”次数var rand=数学地板(Math.random()*62);//随机:0..61var charCode=rand+=rand>9?(兰特<36?55:61):48;//获取正确的charCodestr+=字符串.fromCharCode(charCode);//将字符添加到str}返回str;//完成所有循环后,返回连接字符串}console.log(randomString(10));//即:“7GL9F0ne6t”

或者,如果您愿意:

const randomString=(n,r=“”)=>{而(n--)r+=String.fromCharCode((r=Math.random()*62|0,r+=r>9?(r<36?55:61):48));返回r;};console.log(randomString(10))

这是我的方法(使用TypeScript)。

我决定写另一个响应,因为我没有看到任何使用现代js和干净代码的简单解决方案。

const DEFAULT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

function getRandomCharFromAlphabet(alphabet: string): string {
  return alphabet.charAt(Math.floor(Math.random() * alphabet.length));
}

function generateId(idDesiredLength: number, alphabet = DEFAULT_ALPHABET): string {
  /**
   * Create n-long array and map it to random chars from given alphabet.
   * Then join individual chars as string
   */
  return Array.from({length: idDesiredLength}).map(() => {
    return getRandomCharFromAlphabet(alphabet);
  }).join('');
}

generateId(5); // jNVv7

喜欢这个SO问题和他们的答案。因此,提出了更具创意的解决方案。我提出了一个封装在函数中的函数,该函数接收要获取的字符串的长度加上一个模式参数,以决定如何编写字符串。

模式是一个3长度的字符串,只接受“1s”和“0s”,它们定义了要在最终字符串中包含的字符子集。它由3个不同的子集([0-9]、[A-B]、[A-B])分组

'100': [0-9]
'010': [A-B]
'101': [0-9] + [a-b]
'111': [0-9] + [A-B] + [a-b]

有8种可能的组合(2^N,其中N:#子集)。“000”模式返回空字符串。

function randomStr(l = 1, mode = '111') {
    if (mode === '000') return '';
    const r = (n) => Math.floor(Math.random() * n);
    const m = [...mode].map((v, i) => parseInt(v, 10) * (i + 1)).filter(Boolean).map((v) => v - 1);
    return [...new Array(l)].reduce((a) => a + String.fromCharCode([(48 + r(10)), (65 + r(26)), (97 + r(26))][m[r(m.length)]]), '')
}

一个简单的用例是:

random = randomStr(50, '101')
// ii3deu9i4jk6dp4gx43g3059vss9uf7w239jl4itv0cth5tj3e
// Will give you a String[50] composed of [0-9] && [a-b] chars only.

这里的主要思想是使用UNICODE表,而不是像我在许多答案中看到的那样随机化十六进制。这种方法的强大之处在于,您可以很容易地将其扩展为包含UNICODE表的其他子集,其中包含一些随机int(16)无法完成的额外代码。

生成10个字符长的字符串。长度由参数设置(默认值为10)。

function random_string_generator(len) {
var len = len || 10;
var str = '';
var i = 0;

for(i=0; i<len; i++) {
    switch(Math.floor(Math.random()*3+1)) {
        case 1: // digit
            str += (Math.floor(Math.random()*9)).toString();
        break;

        case 2: // small letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 97); //'a'.charCodeAt(0));
        break;

        case 3: // big letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 65); //'A'.charCodeAt(0));
        break;

        default:
        break;
    }
}
return str;
}