根据用户详细信息在 Javascript 中创建随机令牌
Posted
技术标签:
【中文标题】根据用户详细信息在 Javascript 中创建随机令牌【英文标题】:Create a random token in Javascript based on user details 【发布时间】:2012-01-21 21:01:18 【问题描述】:我想创建一个随机字符串(令牌),可用于识别用户,同时避免与任何其他用户的令牌发生任何潜在冲突。
我想的是navigator.userAgent + new Date().getTime()
的 MD5 散列来生成令牌,但这需要整个 javascript MD5 库来散列它,而我并不想这样做。
它必须由 A-Z/0-9 个字符组成,最好不超过 32 个字符。我对所有想法持开放态度。谢谢!
为了澄清我不是在寻找任何随机字符串生成器,随机字符串必须从通过 Javascript 获得的用户详细信息生成,并且还可以利用时间来避免潜在的冲突!
【问题讨论】:
正如你所写的,我唯一想到的就是哈希函数。你可能想尝试用谷歌搜索类似“hash function javascript”的东西,也许你会发现一些轻量级的 【参考方案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);
以上是关于根据用户详细信息在 Javascript 中创建随机令牌的主要内容,如果未能解决你的问题,请参考以下文章
如何在 liferay 6.2 CE 中创建一个 UserModelListener,它捕获仅在控制面板-> 用户组织中更新的用户详细信息的数据