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

Generate random string/characters in JavaScript

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

使用JavaScript最好的方法是什么?


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

注:上述算法存在以下缺点:

  • 它将生成0到6个字符之间的任何地方,因为当串接浮点时,尾随零被删除。
  • 它深深地依赖于用来串接浮点数的算法,这是非常复杂的。(见"如何准确打印浮点数"一文。)
  • Math.random()可能产生可预测的(随机查找的)输出,但不是真正随机的),这取决于实现。当需要保证唯一性或不可预测性时,结果字符串不适用。
  • 即使它生成了6个均匀随机、不可预测的字符,由于生日悖论,您也可以在只生成大约50000个字符串后看到一个副本。(平方英尺(36^6)=46656)


我想这对你有用:

1
2
3
4
5
6
7
8
9
10
11
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));


随机数对这种事情不好。

选项1

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

1
2
3
4
var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

//"bb5dc8842ca31d4603d6aa11448d1654"

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

选项2

如果必须这样做,请尝试UUID模块-

1
2
3
4
var uuid = require("uuid");
var id = uuid.v4();

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

选项3

如果必须这样做,并且不必支持旧的浏览器,则可以不依赖于其他浏览器来完成此操作。-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
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"

有关crypto.getRandomValues的更多信息-

The crypto.getRandomValues() method lets you get cryptographically strong random values. The array given as the parameter is filled with random numbers (random in its cryptographic meaning).

下面是一个小控制台示例-

1
2
3
4
5
6
7
8
9
10
11
12
> 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支持,您可以使用-

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

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


短、易、可靠

只返回5个随机字符,而不是这里找到的一些最受欢迎的答案。

1
Math.random().toString(36).substr(2, 5);


这是对Doubletap优秀答案的改进。原件有两个缺点,在这里解决:

首先,正如其他人提到的,它产生短字符串甚至空字符串的概率很小(如果随机数为0),这可能会破坏应用程序。以下是一个解决方案:

1
(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

其次,上面的原始和解决方案都将字符串大小n限制为16个字符。对于任何n,下面将返回一个大小为n的字符串(但请注意,使用n>16不会增加随机性或降低碰撞概率):

1
Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

说明:

  • 在范围[0,1]中选择一个随机数,即介于0(含)和1(不含)之间。
  • 将数字转换为base-36字符串,即使用字符0-9和a-z。
  • 用零填充(解决第一个问题)。
  • 切掉前导"0."前缀和额外的填充零。
  • 重复该字符串足够多次,使其至少包含n个字符(通过将空字符串与用作分隔符的较短随机字符串连接起来)。
  • 从字符串中精确切片n个字符。
  • 进一步思考:

    • 此解决方案不使用大写字母,但在几乎所有情况下(不打算使用双关语),这并不重要。
    • 原始答案中n=16处的最大字符串长度用铬测量。在火狐中,它是n=11。但是正如所解释的,第二个解决方案是支持任何请求的字符串长度,而不是增加随机性,所以它没有什么区别。
    • 所有返回的字符串都有相同的返回概率,至少在math.random()返回的结果均匀分布的情况下(在任何情况下,这都不是加密强度的随机性)。
    • 并非所有可能的大小为n的字符串都可以返回。在第二种解决方案中,这是显而易见的(因为较小的字符串只是简单地被复制),但在原始答案中,这是正确的,因为在转换为base-36时,最后几个位可能不是原始随机位的一部分。具体来说,如果查看math.random().toString(36)的结果,您会发现最后一个字符的分布不均匀。同样,在几乎所有的情况下,它都不重要,但是我们从随机字符串的开始而不是结束分割最后一个字符串,这样短字符串(例如n=1)就不会受到影响。

    更新:

    这是我想出的另外两个功能风格的一句话。它们与上述解决方案的不同之处在于:

    • 他们使用一个明确的任意字母表(更通用,并且适用于要求大写和小写字母的原始问题)。
    • 所有长度为n的字符串都有相同的返回概率(即字符串不包含重复)。
    • 它们基于一个映射函数,而不是ToString(36)技巧,这使得它们更加简单易懂。

    所以说你选择的字母表是

    1
    var s ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    然后这两个值是相等的,因此您可以选择对您更直观的值:

    1
    Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

    1
    Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

    编辑:

    我似乎是库比特和马蒂金·德米利亚诺想出了类似于后者的解决方案(荣誉!)我不知怎么地错过了。既然它们看起来不那么短,我还是把它放在这儿,以防有人真的想要一条单线纸。

    此外,在所有解决方案中,将"new array"替换为"array",以减少更多的字节。


    像这样的东西应该管用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function randomString(len, charSet) {
        charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        var randomString = '';
        for (var i = 0; i < len; i++) {
            var randomPoz = Math.floor(Math.random() * charSet.length);
            randomString += charSet.substring(randomPoz,randomPoz+1);
        }
        return randomString;
    }

    使用默认字符集[A-ZA-Z0-9]调用或自己发送:

    1
    2
    3
    var randomValue = randomString(5);

    var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function randomstring(L) {
      var s = '';
      var randomchar = function() {
        var n = Math.floor(Math.random() * 62);
        if (n < 10) return n; //1-10
        if (n < 36) return String.fromCharCode(n + 55); //A-Z
        return String.fromCharCode(n + 61); //a-z
      }
      while (s.length < L) s += randomchar();
      return s;
    }
    console.log(randomstring(5));


    最紧凑的解决方案,因为slicesubstring短。从字符串末尾减去可以避免由random函数生成的浮点符号:

    1
    Math.random().toString(36).slice(-5);

    甚至

    1
    (+new Date).toString(36).slice(-5);

    1
    2
    3
    4
    5
    // Using Math.random
    console.log(Math.random().toString(36).slice(-5));

    // Using new Date
    console.log((+new Date).toString(36).slice(-5));


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
     * RANDOM STRING GENERATOR
     *
     * Info:      http://stackoverflow.com/a/27872144/383904
     * Use:       randomString(length [,"A"] [,"N"] );
     * Default:   return a random alpha-numeric string
     * Arguments: If you use the optional"A","N" flags:
     *           "A" (Alpha flag)   return random a-Z string
     *           "N" (Numeric flag) return random 0-9 string
     */

    function randomString(len, an){
        an = an&&an.toLowerCase();
        var str="", i=0, min=an=="a"?10:0, max=an=="n"?10:62;
        for(;i++<len;){
          var r = Math.random()*(max-min)+min <<0;
          str += String.fromCharCode(r+=r>9?r<36?55:61:48);
        }
        return str;
    }
    1
    2
    3
    randomString(10);        //"4Z8iNQag9v"
    randomString(10,"A");   //"aUkZuHNcWw"
    randomString(10,"N");   //"9055739230"

    玩得高兴。JSBN演示

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

    • 创建接受参数的函数(随机字符串结果的所需长度)
    • 创建一个像var str ="";这样的空字符串来连接随机字符
    • 在循环内创建从0到61(0..9+a..z+a..z=62)的rand索引号。
    • 创建一个条件逻辑来调整/修复rand(因为它是0..61),将它增加一些数字(见下面的例子),以返回正确的CharCode数字和相关字符。
    • 在连接到stra String.fromCharCode( incremented rand )的循环内部

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

    1
    2
    3
    _____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的范围(我们需要的)。如何固定(增加)随机数以获得正确的字符码范围?

    1
    2
    3
    4
    5
          |   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     |

    上表中的条件运算逻辑:

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

    如果按照上述说明进行操作,您应该能够创建这个字母数字片段:

    JSBN演示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function randomString( len ) {
      var str ="";                                         // String result
      for(var i=0; i<len; i++){                             // Loop `len` times
        var rand = Math.floor( Math.random() * 62 );        // random: 0..61
        var charCode = rand+= rand>9? (rand<36?55:61) : 48; // Get correct charCode
        str += String.fromCharCode( charCode );             // add Character to str
      }
      return str;       // After all loops are done, return the concatenated string
    }

    console.log( randomString(10) ); //"7GL9F0ne6t"

    或者如果你愿意:

    1
    2
    3
    4
    5
    function randomString( n ) {
      var r="";
      while(n--)r+=String.fromCharCode((r=Math.random()*62|0,r+=r>9?(r<36?55:61):48));
      return r;
    }

    带有ES6 Spread Operator的更新版本:

    [...Array(30)].map(() => Math.random().toString(36)[2]).join('')

    • 30是任意数字,您可以选择任何您想要的令牌长度。
    • 36是可以传递给numeric.toString()的最大基数,表示所有数字和a-z小写字母。
    • 2从随机串中选取2th号,如:"0.mfbiohx64i",可以取0.后的任何索引。


    最简单的方法是:

    1
    (new Date%9e6).toString(36)

    这将根据当前时间生成5个字符的随机字符串。示例输出为4mtxj4mv904mwp1

    问题在于,如果在同一秒内调用它两次,它将生成相同的字符串。

    更安全的方法是:

    1
    (0|Math.random()*9e6).toString(36)

    这将生成一个4或5个字符的随机字符串,始终是不同的。示例输出类似于30jzm1r5914su1a

    第一部分以两种方式生成随机数。.toString(36)部分将数字转换为它的base36(alphadecimal)表示。


    这里有一些简单的一句话。更改new Array(5)以设置长度。

    包括EDOCX1[1]

    1
    new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

    包括0-9a-zA-Z

    1
    new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

    我知道每个人都已经把它做好了,但我想以最轻量级的方式(轻量级代码,而不是CPU)尝试一下:

    1
    2
    3
    4
    5
    6
    function rand(length, current) {
      current = current ? current : '';
      return length ? rand(--length,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
    }

    console.log(rand(5));

    这需要一点时间,但我认为它确实显示了JavaScript的语法是多么的棒。


    如果您使用的是lodash或下划线,那么它非常简单:

    1
    var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');


    这是我创建的方法。
    它将创建一个包含大小写字符的字符串。
    此外,我还包含了将创建字母数字字符串的函数。

    工作示例:
    http://jsfiddle.net/greatbigmassy/vhsxs/(仅限阿尔法)
    http://jsfiddle.net/greatbigmassive/pjwg8/(字母数字)

    1
    2
    3
    4
    5
    6
    7
    8
    function randString(x){
        var s ="";
        while(s.length<x&&x>0){
            var r = Math.random();
            s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
        }
        return s;
    }

    升级2015年7月
    这做了同样的事情,但更有意义,包括所有的字母。

    1
    2
    3
    4
    5
    var s ="";
    while(s.length<x&&x>0){
        v = Math.random()<0.5?32:0;
        s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
    }


    假设您使用下划线,就可以在两行中优雅地生成随机字符串:

    1
    2
    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var random = _.sample(possible, 5).join('');


    为满足要求[A-ZA-Z0-9]和长度=5,使用

    1
    btoa(Math.random()).substr(5, 5);

    将出现小写字母、大写字母和数字。


    如果任何人对一个一次性分配内存的单行程序感兴趣(尽管不是为了方便而格式化为这样),请注意,对于小字符串来说,这并不重要),下面是如何做到这一点的方法:

    1
    2
    3
    4
    5
    Array.apply(0, Array(5)).map(function() {
        return (function(charset){
            return charset.charAt(Math.floor(Math.random() * charset.length))
        }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
    }).join('')

    您可以将5替换为所需字符串的长度。多亏了本文中的@ariyahidayat,map函数的解决方案无法处理Array(5)创建的稀疏数组。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function getRandomId(length) {
        if (!length) {
            return '';
        }

        const possible =
            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        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);
            }
        }

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

        return result;
    }


    您可以循环遍历一个项目数组并递归地将它们添加到字符串变量中,例如,如果您想要一个随机的DNA序列:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function randomDNA(len) {
      len = len || 100
      var nuc = new Array("A","T","C","G")
      var i = 0
      var n = 0
      s = ''
      while (i <= len - 1) {
        n = Math.floor(Math.random() * 4)
        s += nuc[n]
        i++
      }
      return s
    }

    console.log(randomDNA(5));


    我没有找到同时支持小写和大写字符的干净解决方案。

    仅支持小写:

    Math.random().toString(36).substr(2, 5)

    基于该解决方案支持小写和大写:

    Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

    更改substr(2, 5)中的5以调整到所需的长度。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function randomString (strLength, charSet) {
        var result = [];

        strLength = strLength || 5;
        charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

        while (--strLength) {
            result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
        }

        return result.join('');
    }

    这是最干净的。它也很快,http://jspef.com/ay-random-string。


    这当然行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <script language="javascript" type="text/javascript">
    function randomString() {
     var chars ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
     var string_length = 8;
     var randomstring = '';
     for (var i=0; i<string_length; i++) {
      var rnum = Math.floor(Math.random() * chars.length);
      randomstring += chars.substring(rnum,rnum+1);
     }
     document.randform.randomfield.value = randomstring;
    }

    您可以使用coderain。它是一个根据给定模式生成随机代码的库。使用#作为大小写字符以及数字的占位符:

    1
    2
    var cr = new CodeRain("#####");
    console.log(cr.next());

    还有其他占位符,如大写字母的A,数字的9

    可能有用的是,调用.next()总是会给您一个独特的结果,因此您不必担心重复。

    这里是一个演示应用程序,它生成一个唯一的随机代码列表。

    完全公开:我是《法典》的作者。


    回答"我需要随机字符串"问题(无论用什么语言)的问题实际上是每个解决方案都使用了有缺陷的字符串长度的主要规范。这些问题本身很少揭示为什么需要随机字符串,但我要挑战的是,你很少需要长度为8的随机字符串。您永远需要的是一些唯一的字符串,例如,为了某种目的用作标识符。

    有两种获得严格唯一字符串的主要方法:确定性(非随机)和存储/比较(繁重)。我们该怎么办?我们放弃鬼魂。我们改为使用概率唯一性。也就是说,我们接受存在一些(无论多小)风险,我们的字符串不会是唯一的。这是理解碰撞概率和熵有帮助的地方。

    因此,我将把不变的需求重新表述为需要一些具有小重复风险的字符串。作为一个具体的例子,假设您希望生成一个潜在的500万个ID。您不希望存储和比较每个新字符串,并且希望它们是随机的,所以您接受了一些重复的风险。例如,假设重复的概率小于1万亿分之一。所以你需要多长的绳子?好吧,这个问题没有具体说明,因为它取决于使用的字符。但更重要的是,它被误导了。您需要的是字符串熵的规范,而不是它们的长度。熵可以直接与某些字符串的重复概率有关。字符串长度不能。

    这就是像entropyString这样的库可以提供帮助的地方。使用entropy-string生成随机ID,其在500万个字符串中重复的概率小于1万亿分之一:

    1
    2
    3
    4
    5
    6
    import {Random, Entropy} from 'entropy-string'

    const random = new Random()
    const bits = Entropy.bits(5e6, 1e12)

    const string = random.string(bits)

    "44hTNghjNHGGRHqH9"

    entropy-string默认使用32个字符的字符集。还有其他预定义的字符集,您也可以指定自己的字符。例如,使用与上面相同的熵生成ID,但使用十六进制字符:

    1
    2
    3
    4
    5
    6
    import {Random, Entropy, charSet16} from './entropy-string'

    const random = new Random(charSet16)
    const bits = Entropy.bits(5e6, 1e12)

    const string = random.string(bits)

    "27b33372ade513715481f"

    请注意,由于所用字符集中的字符总数不同,字符串长度也不同。在指定数量的潜在字符串中重复的风险相同。字符串长度不是。最重要的是,重复的风险和潜在的字符串数量是明确的。不用再猜测绳子的长度了。


    像这样的东西怎么样:Date.now().toString(36)。不是很随机,但很短,每次你叫它都很独特。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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;
    }

    不区分大小写的字母数字字符:

    1
    2
    3
    4
    5
    6
    7
    8
    function randStr(len) {
      let s = '';
      while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
      return s;
    }

    // usage
    console.log(randStr(50));

    这个函数的好处是,您可以得到不同长度的随机字符串,并确保字符串的长度。

    区分大小写所有字符:

    1
    2
    3
    4
    5
    6
    7
    8
    function randStr(len) {
      let s = '';
      while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
      return s;
    }

    // usage
    console.log(randStr(50));

    定制字符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function randStr(len, chars='abc123') {
      let s = '';
      while (len--) s += chars[Math.floor(Math.random() * chars.length)];
      return s;
    }

    // usage
    console.log(randStr(50));
    console.log(randStr(50, 'abc'));
    console.log(randStr(50, 'aab')); // more a than b


    这是1个答案的测试脚本(谢谢@csharptest.net)

    脚本运行makeid()1 million次,正如您所看到的,5不是非常独特的。以10个字符的长度运行它是相当可靠的。我已经跑了50次了,还没有看到复制品。

    注意:节点堆栈大小限制超过了400万左右,所以您不能运行这500万次,它永远不会完成。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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');

    这个小把戏怎么样?

    1
    2
    3
    4
    5
    6
    7
    8
    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var stringLength = 5;

    function pickRandom() {
        return possible[Math.floor(Math.random() * possible.length)];
    }

    var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

    你需要有Array.apply来欺骗空数组成为一个未定义数组。

    如果您要为ES2015编码,那么构建阵列就要简单一点:

    1
    var randomString = Array.from({ length: stringLength }, pickRandom).join('');

    通过回答Gertas和Dragon提出的问题,扩展Doubletap的优雅典范。只需添加一个while循环来测试这些罕见的空情况,并将字符限制为5个。

    1
    2
    3
    4
    5
    6
    7
    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;
    }

    下面是一个jsiddle,它向您发出一个结果警告:http://jsfiddle.net/pljj7/


    这是我用过的。一对组合在一起。我在一个循环中使用它,它产生的每个ID都是唯一的。它可能不是5个字符,但肯定是独一无二的。

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


    如果库是可能的,chance.js可能会有帮助:http://chance js.com/string


    这个结合了许多答案。

    1
    2
    3
    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
    2
    3
    4
    5
    6
    7
    8
    function getRandomStrings(length) {
      const value = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      const randoms = [];
      for(let i=0; i < length; i++) {
         randoms.push(value[Math.floor(Math.random()*value.length)]);
      }
      return randoms.join('');
    }

    但是如果您在ES6中寻找一个较短的语法:

    1
    const getRandomStrings = length => Math.random().toString(36).substr(-length);

    同样基于DoubleTap的答案,这个函数处理任意长度的随机必需字符(仅下方),并不断生成随机数,直到收集到足够的字符为止。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function randomChars(len) {
        var chars = '';

        while (chars.length < len) {
            chars += Math.random().toString(36).substring(2);
        }

        // Remove unnecessary additional characters.
        return chars.substring(0, len);
    }

    1
    2
    3
    4
    5
    "12345".split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');

    //or

    String.prototype.rand = function() {return this.split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');};

    将生成具有第一个/调用字符串长度的随机字母数字字符串


    1
    ",,,,,".replace(/,/g,function (){return"AzByC0xDwEv9FuGt8HsIrJ7qKpLo6MnNmO5lPkQj4RiShT3gUfVe2WdXcY1bZa".charAt(Math.floor(Math.random()*62))});


    对于具有大小写字母和数字(0-9a-z a-z)的字符串,这可能是最适合缩小的版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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个字节(因为字符列表)。


    这是Doubletap答案的一个稍微改进的版本。当Math.random()返回0、0.5、0.25、0.125等时,考虑了gertas对此案的评论。

    1
    ((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)
  • 它防止将零传递给toString,我将最小的浮点数添加到Math.random()
  • 它确保传递给toString的数字除以一个几乎不合理的数字就足够了。

  • 教人钓鱼:

    程序员用激光切割纸张,而不是用链锯。使用边缘,语言特定的方法来产生最小的,最模糊的代码是可爱的和所有,但永远不会提供一个完整的解决方案。你必须使用合适的工具来完成这项工作。

    您需要的是一个字符串,字符由字节表示。而且,我们可以用数字在JavaScript中表示一个字节。那么,我们应该生成一个这些数字的列表,并将它们转换为字符串。你不需要日期,或者base64;math.random()会给你一个数字,string.fromcharcode()会把它变成一个字符串。容易的。

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

    UTF-8以0到128之间的数字列出键盘上的所有键。有些是非印刷品。只需在随机字符串中挑选您想要的字符,然后使用随机生成的数字搜索它们。

    Bellow是一个函数,它的长度实际上是无限的,在一个循环中生成一个随机数,并搜索下面128个UTF-8代码中的所有打印字符。熵是固有的,因为并非所有随机数都会每次命中(非打印字符、空白等)。当您添加更多的字符时,它的执行速度也会更快。

    我已经包含了线程中讨论的大多数优化:

    • 双层瓷砖比数学地板快。
    • "if"语句比正则表达式快
    • 推到数组比字符串串联更快

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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';
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #length {
      width: 3em;
      color: #484848;
    }

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

    为什么要这样乏味?因为你可以。你是个程序员。你可以让电脑做任何事!另外,如果你想要一串希伯来文字符怎么办?这并不难。在UTF-8标准中查找这些字符并搜索它们。把自己从像ToString(36)这样的麦当劳方法中解放出来。

    有时,降低抽象级别是创建真正的解决方案所需要的。了解手边的基本原理可以让您根据自己的喜好定制代码。也许您需要无限生成的字符串来填充循环缓冲区?也许你希望所有生成的字符串都是回文?为什么要克制自己?


    随机Unicode字符串

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

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

    理论基础

    这是谷歌在搜索"随机字符串javascript"时的首要结果,但OP只要求a-za-z0-9。


    随机数值(最多16位)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
     * Random numeric value (up to 16 digits)
     * @returns {String}
     */

    function randomUid () {
      return String(Math.floor(Math.random() * 9e15))
    }

    // randomUid() ->"3676724552601324"

    我喜欢doubletap的math.random().tostring(36).substring(7)答案的敏捷性,但并不像hacklikecrack正确指出的那样,它有如此多的碰撞。它生成了11个字符字符串,但在100万个样本中的重复率为11%。

    这里有一个较长(但仍然较短)和较慢的替代方案,在100万个样本空间中只有133个副本。在极少数情况下,字符串仍将短于11个字符:

    1
    2
    Math.abs(Math.random().toString().split('')
        .reduce(function(p,c){return (p<<5)-p+c})).toString(36).substr(0,11);


    我用的是var randId = 'rand' + new Date().getTime();


    这将在变量C中存储5个字母数字字符。

    1
    for(var c = ''; c.length < 5;) c += Math.random().toString(36).substr(2, 1)

    这里有一种不同的方法,按基固定长度,不使用regexp替换lack(基于@bendytree的答案);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function rand(base) {
        // default base 10
        base = (base >= 2 && base <= 36) ? base : 10;
        for (var i = 0, ret = []; i < base; i++) {
            ret[i] = ((Math.random() * base) | 0).toString(base)
                // include 0-9a-zA-Z?
                // [Math.random() < .5 ? 'toString' : 'toUpperCase']();
        }
        return ret.join('');
    }

    正如这里的一些人指出的,将Math.random()的结果直接传递给.string(36)有几个问题。

    随机性差。生成的字符数各不相同,平均情况下取决于浮点数字在JavaScript中如何工作的复杂细节。如果我尝试生成11个或更少的字符,但不超过11个字符,这似乎是可行的。它也不灵活。不容易允许或禁止某些字符。

    我有一个紧凑的解决方案,它不存在这些问题,对于任何使用lodash的人:

    1
    _.range(11).map(i => _.sample("abcdefghijklmnopqrstuvwxyz0123456789")).join('')

    如果要允许某些字符(如大写字母)或禁止某些字符(如l1等不明确字符),请修改上面的字符串。


    非常简单

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

    试试这个,我每次都用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!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>


    在下面的代码中,我生成了8个字符的随机代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);

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

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

    一种实用的方法。只有在应用程序的其他部分可以利用功能先决条件时,此答案才是可行的。这个表演可能是垃圾,但写起来非常有趣。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    // functional prerequisites
    const U = f=> f (f)
    const Y = U (h=> f=> f (x=> h (h) (f) (x)))
    const comp = f=> g=> x=> f (g (x))
    const foldk = Y (h=> f=> y=> ([x, ...xs])=>
      x === undefined ? y : f (y) (x) (y=> h (f) (y) (xs)))
    const fold = f=> foldk (y=> x=> k=> k (f (y) (x)))
    const map = f=> fold (y=> x=> [...y, f (x)]) ([])
    const char = x=> String.fromCharCode(x)
    const concat = x=> y=> y.concat(x)
    const concatMap = f=> comp (fold (concat) ([])) (map (f))
    const irand = x=> Math.floor(Math.random() * x)
    const sample = xs=> xs [irand (xs.length)]

    // range : make a range from x to y; [x...y]
    // Number -> Number -> [Number]
    const range = Y (f=> r=> x=> y=>
      x > y ? r : f ([...r, x]) (x+1) (y)
    ) ([])

    // srand : make random string from list or ascii code ranges
    // [(Range a)] -> Number -> [a]
    const srand = comp (Y (f=> z=> rs=> x=>
      x === 0 ? z : f (z + sample (rs)) (rs) (x-1)
    ) ([])) (concatMap (map (char)))

    // idGenerator : make an identifier of specified length
    // Number -> String
    const idGenerator = srand ([
      range (48) (57),  // include 0-9
      range (65) (90),  // include A-Z
      range (97) (122)  // include a-z
    ])

    console.log (idGenerator (6))  //=> TT688X
    console.log (idGenerator (10)) //=> SzaaUBlpI1
    console.log (idGenerator (20)) //=> eYAaWhsfvLDhIBID1xRh

    在我看来,如果不增加魔法,做太多事情的功能,就很难打破idGenerator的清晰性。

    可能会有轻微的改善

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // ord : convert char to ascii code
    // Char -> Number
    const ord = x => x.charCodeAt(0)

    // idGenerator : make an identifier of specified length
    // Number -> String
    const idGenerator = srand ([
      range (ord('0')) (ord('9')),
      range (ord('A')) (ord('Z')),
      range (ord('a')) (ord('z'))
    ])

    玩得开心。告诉我你喜欢什么/学习什么^^


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

    如果需要特殊字符,也可以进行分解,并且可以避免使用某些字符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
     * 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;
    };

    您可以这样使用:

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

    希望它有帮助。


    这是用于Firefox Chrome代码(插件等)

    它可以帮你节省几个小时的研究时间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function randomBytes( amount )
    {
        let bytes = Cc[ '@mozilla.org/security/random-generator;1' ]

            .getService         ( Ci.nsIRandomGenerator )
            .generateRandomBytes( amount, ''            )

        return bytes.reduce( bytes2Number )


        function bytes2Number( previousValue, currentValue, index, array )
        {
          return Math.pow( 256, index ) * currentValue + previousValue
        }
    }

    使用它作为:

    1
    2
    3
    let   strlen   = 5
        , radix    = 36
        , filename = randomBytes( strlen ).toString( radix ).splice( - strlen )

    递归解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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)

    }

    你可以使用你想要的种子,如果你不想,不要重复字符。例子

    1
    generateRandomId("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")

    您可以使用base64:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function randomString(length)
    {
        var rtn ="";

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

        return rtn;
    }

    另一种将字符A-Za-z0-9中的字符串随机化的好方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function randomString(length) {
        if ( length <= 0 ) return"";
        var getChunk = function(){
            var i, //index iterator
                rand = Math.random()*10e16, //execute random once
                bin = rand.toString(2).substr(2,10), //random binary sequence
                lcase = (rand.toString(36)+"0000000000").substr(0,10), //lower case random string
                ucase = lcase.toUpperCase(), //upper case random string
                a = [lcase,ucase], //position them in an array in index 0 and 1
                str =""; //the chunk string
            b = rand.toString(2).substr(2,10);
            for ( i=0; i<10; i++ )
                str += a[bin[i]][i]; //gets the next character, depends on the bit in the same position as the character - that way it will decide what case to put next
            return str;
        },
        str =""; //the result string
        while ( str.length < length  )
            str += getChunk();
        str = str.substr(0,length);
        return str;
    }

    将字符作为thisArg放入map函数将创建一个"一行程序":

    1
    2
    3
    4
    5
    Array.apply(null, Array(5))
    .map(function(){
        return this[Math.floor(Math.random()*this.length)];
    },"abcdefghijklmnopqrstuvwxyz")
    .join('');

    下面是CoffeeDescript中的一个示例:

    1
    2
    3
    String::add_Random_Letters   = (size )->
                                             charSet = 'abcdefghijklmnopqrstuvwxyz'
                                             @ + (charSet[Math.floor(Math.random() * charSet.length)]  for i in [1..size]).join('')

    可以使用的

    1
    2
    value ="abc_"
    value_with_exta_5_random_letters = value.add_Random_Letters(5)

    这是CoffeeScript版本一行代码

    1
    genRandomString = (length,set) -> [0...length].map( -> set.charAt Math.floor(Math.random() * set.length)).join('')

    用途:

    1
    genRandomString 5, 'ABCDEFTGHIJKLMNOPQRSTUVWXYZ'

    输出:

    1
    'FHOOV' # random string of length 5 in possible set A~Z