Как получается случайность с помощью Math.random в javascript?

17

Как достигается случайность с помощью Math.random в javascript? Я сделал что-то, что выбирает между 50 различными вариантами случайным образом. Мне интересно, как мне комфортно пользоваться Math.random, чтобы получить мою случайность.     

задан David 26.02.2010 в 20:37
источник
  • @David: это не правда, случайность, как вы знаете. Приписывается Джону фон Нейману: «Любой, кто рассматривает арифметические методы производства случайных цифр, конечно, находится в состоянии греха». Они используют PRNG. Генератор псевдослучайных чисел. –  cocotwo 26.02.2010 в 20:40
  • @cocotwo: это не значит, что все JS должны быть psuedo random, из спецификации Bob, размещенной ниже, она может быть реальной случайной. Реализация будет использовать только настоящий RNG, что не так сложно, как когда-то было. –  Neil N 26.02.2010 в 20:51
  • Как говорится в некоторых ответах ниже, это действительно зависит от того, что вы хотите сделать. Я подозреваю, что в 99% случаев Math.random в порядке, но это потенциально можно предсказать. –  Alex Wayne 26.02.2010 в 20:52

5 ответов

14

Из спецификаций:

  

случайным образом ():      

Возвращает значение числа с положительным   знак, больше или равно 0, но   менее 1, выбранных случайным образом или псевдо   случайным образом с приблизительно однородным   распределения по этому диапазону, используя   зависящий от реализации алгоритм или   стратегия. Эта функция не принимает   Аргументы.

Итак, ответ заключается в том, что это зависит от того, какой движок JavaScript вы используете.

Я не уверен, что все браузеры используют ту же стратегию или что эта стратегия, к сожалению,

Это должно быть хорошо для ваших целей. Только если вы делаете большое количество чисел, вы начнете видеть шаблон

    
ответ дан Bob 26.02.2010 в 20:41
  • @cocotow et al. Мне было интересно погоду или нет, что psudo-randomness это хорошо или нет? как я бы догадался, что его поробобли не достаточно хорош для вегаса или науки, но достаточно ли это для повседневных нужд? (я сделал что-то, что будет принимать решения для меня, основываясь на списке возможных децизонов. –  David 26.02.2010 в 20:52
  • Это достаточно хорошо для повседневных нужд, что и есть для Javascript's Math.random (). Хорошо. –  John Feminella 26.02.2010 в 20:53
  • @JohnFeminella Пожалуйста, определите "повседневные потребности" –  user877329 23.04.2015 в 12:19
  • @Bob это только о семени. Не тот двигатель, который он использует. –  user877329 23.04.2015 в 12:20
  • @ user877329: Если вы хотите случайное число, которое не будет использоваться в качестве источника энтропии (например, для криптографических целей или где вам абсолютно необходимо гарантировать случайность, например, в казино), то Math.random () отлично , В противном случае не используйте его. –  John Feminella 23.04.2015 в 16:46
11

Использование Math.random () отлично, если вы не имеете централизованного объединения и amp; используя результаты, то есть для OAuth.

Например, наш сайт использовал Math.random () для генерации случайных строк «nonce» для использования с OAuth. Оригинальная библиотека JavaScript сделала это, выбирая символ из предопределенного списка, используя Math.random (): ie

for (var i = 0; i < length; ++i) {
    var rnum = Math.floor(Math.random() * chars.length);
    result += chars.substring(rnum, rnum+1);
}

Проблема заключается в том, что пользователи получали повторяющиеся строки nonce (даже используя 10 символов длиной - теоретически ~ 10 ^ 18 комбинаций), обычно в течение нескольких секунд друг от друга. Я предполагаю, что это связано с посещением Math.random () из временной метки, как упоминалось в одном из других плакатов.

    
ответ дан Nick Baicoianu 28.07.2010 в 22:42
  • +1 для описания того, как поселение на основе временной метки может генерировать повторяющиеся числа в параллельных средах. –  Twilite 15.02.2013 в 14:48
3

Точная реализация может, конечно, несколько отличаться в зависимости от браузера, но все они используют какой-то генератор псевдослучайных чисел. Хотя это не случайно, это, безусловно, достаточно хорошо для всех общих целей.

Вам следует беспокоиться только о случайности, если вы используете его для чего-то, что требует исключительно хорошей случайности, например, для шифрования или моделирования случайной игры в игре за деньги, но в любом случае вы вряд ли будете использовать Javascript.

    
ответ дан Guffa 26.02.2010 в 20:46
2

Это 100% случайным образом для ваших целей . Это посеяно по времени, поэтому каждый раз, когда вы запускаете его, вы получите разные результаты.

Вставьте это в адресную строку браузера ...

javascript:alert(Math.random() * 2 > 1);

и несколько раз нажмите [Enter] ... Я получил «true, false, false, true» - достаточно случайный:)

    
ответ дан Timothy Khouri 26.02.2010 в 20:44
  • В вашем примере кода не отображается случайность генератора случайных чисел, так как вы ввели перекос. Это приведет к более ложным значениям, чем истинные значения. Очень небольшое различие, но все же пример того, как вы можете уменьшить качество случайности, используя это неправильно. –  Guffa 26.02.2010 в 20:50
  • Правда ... но если бы у меня было 50 флажков ... даже образец, который я дал, был бы достаточно хорош для вопроса Дэвида. –  Timothy Khouri 26.02.2010 в 20:53
1

Это немного перебор ... но я не мог удержаться от этого:)

Вы можете выполнить это в адресной строке браузера. Он генерирует случайное число от 0 до 4, 100000 раз. И выводит количество раз, когда каждое число было сгенерировано, и количество раз, когда одно случайное число соответствовало другому.

Я выполнил это в Firefox 3.5.2. Все числа кажутся примерно равными - это указывает на отсутствие смещения и отсутствие очевидного шаблона в том, как генерируются числа.

javascript:
var max = 5;
var transitions = new Array(max);
var frequency = new Array(max);
for (var i = 0; i < max; i++)
{
     transitions[i] = new Array(max);
}
var old = 0, curr = 0;
for (var i = 0; i < 100000; i++)
{
   curr = Math.floor(Math.random()*max);
   if (frequency[curr] === undefined) 
   {
      frequency[curr] = -1;
   }
   frequency[curr] += 1;
   if (transitions[old][curr] === undefined)
   {
      transitions[old][curr] = -1;
   }
   transitions[old][curr] += 1;
   old = curr;
}
alert(frequency);
alert(transitions);
    
ответ дан Aishwar 26.02.2010 в 21:13
  • Это совсем не избыток - этого недостаточно. Глядя на дистрибутив, вы ничего не расскажете о качестве энтропии, и, как говорили другие, точное поведение зависит от реализации, поэтому тестирование Firefox 3.5.2 ничего не говорит о общей ситуации. –  Chris Martin 08.06.2015 в 22:46