【问题标题】:Create a random token in Javascript based on user details根据用户详细信息在 Javascript 中创建随机令牌
【发布时间】:2012-01-21 21:01:18
【问题描述】:

我想创建一个随机字符串(令牌),可用于识别用户,同时避免与任何其他用户的令牌发生任何潜在冲突。

我想的是navigator.userAgent + new Date().getTime() 的 MD5 散列来生成令牌,但这需要整个 Javascript MD5 库来散列它,而我并不想这样做。

它必须由 A-Z/0-9 个字符组成,最好不超过 32 个字符。我对所有想法持开放态度。谢谢!

为了澄清我不是在寻找任何随机字符串生成器,随机字符串必须从通过 Javascript 获得的用户详细信息生成,并且还可以利用时间来避免潜在的冲突!

【问题讨论】:

  • 正如你所写的,我唯一想到的就是哈希函数。你可能想尝试用谷歌搜索类似“hash function javascript”的东西,也许你会发现一些轻量级的

标签: javascript jquery random token


【解决方案1】:

这不太可能,但 Math.random() 可以返回 0.0。在这种情况下,pimvdb 的解决方案将返回 ""(空字符串)。因此,这是另一种解决方案,它在每种情况下都会返回一个随机 base36,长度为 10 个字符:

function generateToken() {
    return Math.floor(1000000000000000 + Math.random() * 9000000000000000)
          .toString(36).substr(0, 10)
}

【讨论】:

    【解决方案2】:

    //length: defines the length of characters to express in the string
    
    const rand=()=>Math.random(0).toString(36).substr(2);
    const token=(length)=>(rand()+rand()+rand()+rand()).substr(0,length);
    
    console.log(token(40));
    //example1:  token(10) => result: tsywlmdqu6
    //example2:  token(40) => result: m4vni14mtln2547gy54ksclhcv0dj6tp9fhs1k10

    【讨论】:

      【解决方案3】:

      我使用类似于Kareem's 的方法,但使用更少的函数调用和内置数组操作来大幅提升性能。

      根据performance test,此方法的性能也略微优于已接受的答案。此外,它提供了一个参数n 以从可接受字符的白名单中生成任意大小的令牌长度。它灵活且性能良好。

      function generateToken(n) {
          var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
          var token = '';
          for(var i = 0; i < n; i++) {
              token += chars[Math.floor(Math.random() * chars.length)];
          }
          return token;
      }
      

      【讨论】:

        【解决方案4】:

        此功能允许您设置令牌长度和允许的字符。

        function generate_token(length){
            //edit the token allowed characters
            var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
            var b = [];  
            for (var i=0; i<length; i++) {
                var j = (Math.random() * (a.length-1)).toFixed(0);
                b[i] = a[j];
            }
            return b.join("");
        }
        

        只需调用 generate_token

        generate_token(32); //returns "qweQj4giRJSdMNzB8g1XIa6t3YtRIHPH"
        

        【讨论】:

        • 另一个答案更小更快,但我喜欢这个让你选择长度和允许的字符的事实。
        【解决方案5】:

        结帐crypto.js 项目。它是一组密码算法。该项目对每种哈希算法都有单独的 js 文件。

        【讨论】:

        • 好的,我已经放弃使用 MD5,crypto 看起来像一个小型库,谢谢!
        • 不要使用 md5。它不耐碰撞。
        【解决方案6】:

        您可以生成一个随机数并将其转换为基数 36 (0-9a-z):

        var rand = function() {
            return Math.random().toString(36).substr(2); // remove `0.`
        };
        
        var token = function() {
            return rand() + rand(); // to make it longer
        };
        
        token(); // "bnh5yzdirjinqaorq0ox1tf383nb3xr"
        

        【讨论】:

        • @fire:我认为这实际上不会引起冲突。理论上 MD5 也会导致冲突,但您不必担心这一点。
        • 如果令牌是通过某人自己的浏览器信息生成的+您的方法会更好,这可能会发生冲突。
        • @fire:我不完全明白你的意思。 navigator.userAgent 并不是每个人都是独一无二的,所以它不能让它防弹。
        • 在rand 函数中从.toString 中删除radix (36) 参数将为您提供纯数字哈希——如果有人想要这样的哈希:return Math.random().toString().substr(2);
        猜你喜欢
        • 2019-12-01
        • 2016-11-29
        • 2017-10-11
        • 1970-01-01
        • 1970-01-01
        • 2018-08-12
        • 2021-12-13
        • 1970-01-01
        • 2016-12-14
        相关资源
        最近更新 更多