ActionScript 2.0中的替代随机源

时间:2010-05-17 20:06:31

标签: flash random actionscript-2

我写了一个在横幅广告中运行的软件,每天产生数百万个会话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。不过,我真的很感激你的答案。

5 个答案:

答案 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)

据我所知,有三种可能性:

  1. 实现并使用另一个伪随机数生成器算法,以便可以指定种子(但问题是如何正确播种,系统时间可能不够)。有一个名为Mersenne Twister的应该是好的。
  2. 使用屏幕分辨率,麦克风名称等所有可能的属性,并通过添加和乘以字符和字符位置来生成指纹。希望这会产生一个有点独特的数字,与Math.random()结合就足够了。
  3. 利用客户端的计时属性,例如,设置X毫秒的超时并测量实际延迟,这将取决于具体情况。如果与Math.random()结合使用可能就足够了,或者它可以用作自定义生成器的种子。

答案 4 :(得分:-1)

如果我理解你的问题,你不需要一个随机数,而是每个电脑的唯一ID。您是否考虑过网卡的MAC地址?

我不知道你是否可以在AS2中获得它,但这会为每台机器提供一个唯一的ID。

也许?另一个想法是

Math.random() * Math.random()

?或

Math.random().toString() + (Math.random() * Math.random()).toString()

不知道,只是一个想法...