我写了一个在横幅广告中运行的软件,每天产生数百万个会话ID。很长一段时间我都知道Flash中的随机数生成器不够随机,无法生成足够唯一的ID,因此我采用了许多技巧来获得更多的随机数。但是,在ActionScript 2.0中,它并不容易,我看到越来越多的碰撞,所以我想知道是否有一些我忽略的东西。
据我所知Math.random()
的问题在于它是由系统时间播种的,当你有足够数量的同时尝试时会发生很多碰撞。
在ActionScript 3.0中,我使用System.totalMemory
返回的值作为一些额外的随机性,但在ActionScript 2.0中没有等价物。 AS3还有Font.enumerateFonts
,以及其他一些与系统不同的东西。
我需要的不是完全随机的东西,只是随机的东西可以稀释我从Math.random()
获得的随机性。可以这样想:两个人有可能仅使用Math.random()
生成相同的随机数序列,但两个人生成相同序列的机会和有,比如说,完全相同的字体列表显着降低。
我不能依赖足够的脚本访问权来使用ExternalInterface
来获取用户代理或页面的URL等内容。我不需要建议如何在AS3或任何其他系统或服务器端,仅使用AS2 - 仅使用标准API中提供的内容。
在服务器端,我还将IP地址添加到会话ID,但即使这样还不够(例如,许多大公司使用单个代理服务器,这意味着成千上万的人都拥有相同的IP - - 并且由于他们倾向于使用相同的广告,大致同时查看相同的网站,因此存在许多会话ID冲突。由于各种原因,在服务器端做更多事情是不切实际的。例如,我可以不在服务器端生成随机数并将它们发送到客户端,即使我非常希望能够以这种方式解决它。
到目前为止,我提出的最好的方法是使用麦克风列表(Microphone.names
),但我也尝试使用System.capabilities
中的一些属性进行一些指纹识别,我不确定我可以从中获得多少随机性,但我现在还没有使用它。我希望我忽视了一些事情。
我很抱歉在我的评论中对你的答案表示傲慢,但是,如果你不了解ActionScript 2.0,或者知道伪随机数发生器是如何工作的,请不要尝试回答,它将没有帮助,我会给予downvotes。不过,我真的很感激你的答案。
答案 0 :(得分:2)
我认为你过度思考并试图过于“狡猾”!
您所追求的是GUID(全球唯一标识符)。基本上你需要更长的数字,如果用过的字母也会有所帮助。
在AS2中已经有一些用于生成GUID的类和脚本,但是Adi Reddy Mora's one from www.designscripting.com非常好。
<强> P.S 强> 让我们做数学! Math.random会抛出一个精度为15位小数的浮点数。这是一个巨大的数字。这可能会导致两个人得到相同数字的千分之一的机会(如果这是一个真正随机的数字,但即便有一半是相当渺茫的机会)。另一方面,您提到的任何其他方法都会有相当少的变化。比如基于用户字体列表。两个人安装相同字体的几率是多少?我会说接近1:20,因为大多数人都使用Windows并且只安装了默认字体!
答案 1 :(得分:1)
我认为两个人以随机()序列结束相同种子的机会是可以忽略不计的。 Adobe没有透露使用的方法,但是如果他们使用系统时钟(如你所说),那应该确保碰撞真的很少(自1970年1月1日0:00:000以来的毫秒数应该非常随机)
如果你无论如何都会发生碰撞,我会开始研究其他的algorhythm,它会扼杀random()吐出的数字并在那里寻找随机性降低操作。例如,如果你的algorhythm将它映射到10个域中的1,那么random()在20亿个数字中返回1并没有帮助。如果你提供一些关于你的algorhythm做什么的更多信息,也许我可以更具体。
此外,字体,麦克风或类似物的数量肯定比random()返回的值少几个数量级。
答案 2 :(得分:1)
自从我最后一次在AS 2.0中编码以来已经有一段时间了,但遵循System.totalMemory的想法,可能的方法是测量性能和/或连接速度。这在系统与系统之间存在一些差异,因此如果您将这些值中的一些结合起来,您可以进一步随机化Math.random。
我正在考虑这样的事情:
var init_ms:Number = getTimer();
var dummy:LoadVars = new LoadVars();
dummy.onData = function(success:Boolean):Void {
trace(init_ms);
trace(getTimer());
var elapsed_ms:Number = getTimer() - init_ms;
trace("elapsed_mc: " + elapsed_ms);
}
dummy.load("http://www.example.com/dummy");
var counter:Number = 0;
this.onEnterFrame = function():Void {
counter++;
if(counter >= 20) {
var elapsed_ms:Number = getTimer() - init_ms;
trace("elapsed_mc: " + elapsed_ms);
this.onEnterFrame = null;
}
};
我不记得AS 2.0中的跨域策略究竟是如何工作的,但我认为上面的代码至少会尝试下载crossdomain.xml;但不确定是否允许您从横幅加载外部内容。
另一个也可以给你一些随机性,因为帧之间经过的时间并不是那么精确,并且机器之间有一些差异,甚至考虑到同一台机器。
希望这有帮助。
答案 3 :(得分:0)
据我所知,有三种可能性:
Math.random()
结合就足够了。Math.random()
结合使用可能就足够了,或者它可以用作自定义生成器的种子。答案 4 :(得分:-1)
如果我理解你的问题,你不需要一个随机数,而是每个电脑的唯一ID。您是否考虑过网卡的MAC地址?
我不知道你是否可以在AS2中获得它,但这会为每台机器提供一个唯一的ID。
也许?另一个想法是
Math.random() * Math.random()
?或
Math.random().toString() + (Math.random() * Math.random()).toString()
不知道,只是一个想法...