Альтернативные источники случайности в ActionScript 2.0 - PullRequest
0 голосов
/ 18 мая 2010

Я пишу программный продукт, который запускается внутри баннерной рекламы и генерирует миллионы идентификаторов сеансов каждый день. В течение долгого времени я знал, что генератор случайных чисел во Flash не является достаточно случайным, чтобы генерировать достаточно уникальные идентификаторы, поэтому я использовал несколько приемов, чтобы получить еще больше случайных чисел. Однако в 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-адрес к идентификатору сеанса, но даже этого недостаточно (например, многие крупные компании используют один прокси-сервер, а это означает, что тысячи людей имеют один и тот же IP - - и поскольку они, как правило, смотрят на одни и те же сайты с одной и той же рекламой, примерно в одно и то же время, возникает много коллизий идентификаторов сеансов). Делать больше на стороне сервера по разным причинам нецелесообразно. Я, например, не могу генерировать случайные числа на стороне сервера и отправлять их клиенту, даже если я очень хотел бы иметь возможность решить их таким образом.

Лучшее, что я до сих пор придумал, - это использовать список микрофонов (Microphone.names), но я также попытался сделать дактилоскопию, используя некоторые свойства из System.capabilities, я не уверен, сколько случайности я могу получить от этого, хотя я не использую это в данный момент. Надеюсь, я что-то упустил.

Извините за наглость в комментариях к вашим ответам, но, пожалуйста, если вы не знаете ActionScript 2.0 или не знаете, как работает генератор псевдослучайных чисел, не пытайтесь отвечать , это не поможет, и я буду давать отрицательные отзывы. Я действительно ценю правильные ответы.

Ответы [ 5 ]

2 голосов
/ 18 мая 2010

Я думаю, что вы слишком много думаете об этом и пытаетесь быть слишком "хитрым"!

Что вам нужно, так это GUID (глобально уникальный идентификатор). Как правило, вам нужен более длинный номер, и он также поможет, если использовать буквы.

Уже есть несколько классов и сценариев для генерации GUID в AS2, но Ади Редди Мора из www.designscripting.com действительно хорош.

P.S Давайте посчитаем! Математический случай выплевывает число с точностью до 15 знаков после запятой. Это огромное количество. Это дает шанс один на тысячу миллиардов , когда два человека получат одно и то же число (если это было действительно случайное число, но даже половина из них - довольно слабый шанс). С другой стороны, любой из упомянутых вами методов будет иметь значительно меньшую вариацию. Например, на основе списка шрифтов пользователей. Каковы шансы, что два человека имеют одинаковые шрифты? Я бы сказал, что он близок к 1:20, потому что большинство людей используют окна и имеют только установленные шрифты по умолчанию!

1 голос
/ 21 мая 2010

Прошло много времени с тех пор, как я последний раз кодировал в 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; Не уверен, что вам разрешат загружать внешний контент с баннера.

Другой может также дать вам некоторую случайность, так как время между кадрами не так уж точно и имеет некоторые различия от машины к машине и даже с учетом той же машины.

Надеюсь, это поможет.

1 голос
/ 19 мая 2010

Я думаю, что вероятность того, что два человека получат одно и то же семя для последовательности random (), ничтожна. Adobe не раскрывает используемый метод, но если они используют системные часы (как вы предлагаете), это должно гарантировать, что коллизии действительно редки (количество миллисекунд с 1 января 1970 года 0: 00: 000 должно быть чертовски случайным) .

Если у вас все равно возникают коллизии, я бы начал смотреть на остальную часть алгоритма, который сокращает число, которое выдает random (), и искать там операции по уменьшению случайности. Это не помогает, что random () возвращает число 1 из 2 миллиардов, если ваш алгоритм отображает его, например, в область 1 из 10. Если вы предоставите больше информации о том, что делает ваш алгоритм, возможно, я мог бы быть более конкретным.

Кроме того, количество шрифтов, микрофонов и тому подобного на несколько порядков меньше случайного, чем значение, возвращаемое random ().

0 голосов
/ 19 мая 2010

Насколько я вижу, есть три варианта:

  1. Реализуйте и используйте другой алгоритм генератора псевдослучайных чисел, чтобы можно было задать начальное число (но тогда возникает вопрос, как правильно его заполнить, системного времени, вероятно, недостаточно) Есть один под названием Mersenne Twister , который должен быть хорошим.
  2. Используйте все возможные свойства, такие как разрешение экрана, имена микрофонов и т. Д., И генерируйте отпечаток пальца, добавляя и умножая их символы и положения символов. Надеемся, что это даст несколько уникальное число, которого в сочетании с Math.random() будет достаточно.
  3. Используйте свойства синхронизации клиента, например, установите время ожидания для X миллисекунд и измерьте фактическую задержку, которая будет зависеть от обстоятельств. Этого может быть достаточно в сочетании с Math.random() или его можно использовать в качестве начального числа для пользовательского генератора.
0 голосов
/ 18 мая 2010

Если я правильно понимаю ваш вопрос, вам не нужно случайное число, а уникальный идентификатор для каждого компьютера. Рассматривали ли вы MAC-адрес сетевой карты?

Не знаю, сможете ли вы получить его в AS2, но это даст вам уникальный идентификатор для каждой машины.

Может быть? другая идея будет

Math.random() * Math.random()

? Или

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

не знаю, просто идея ...

...