company_banner

Способы использования Math.random() в JavaScript

Original author: Jwahir Sundai, ruvds_переводы
  • Translation
Math.random() — это один из API JavaScript. Это — функция, которая возвращает случайные числа. Диапазон возвращаемых чисел представлен значениями от 0 (включая 0, то есть, она может вернуть 0) до 1 (не включая 1, то есть — единицу она вернуть не может).

Math.random(); // возвращает случайное число

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



Вот пример, размещённый на CodePen, позволяющий генерировать случайные числа в диапазоне от 0 до 1 и от 0 до 10 (включая 0 и 10).


Пример использования Math.random()

Функцией Math.random() можно воспользоваться в тех случаях, когда в программах нужен элемент случайности. Рассмотрим десять способов применения этой функции. Все примеры, которые тут показаны, созданы разными программистами, которые, пользуясь Math.random(), добиваются различных интересных эффектов.

Анимация


Вот пример, в котором Math.random() используется для создания анимации.


Анимация

Здесь объекты создаются и анимируются с использованием Math.random(). Светящиеся линии случайным образом формируют анимированные шестиугольники.

Музыка, сгенерированная компьютером


Вот проект, демонстрирующий пример использования Math.random() в деле создания компьютерной музыки.


Компьютерная музыка

Здесь за основу взята традиционная мелодия «Auld Lang Syne» («Старое доброе время»). Программа строит итоговую композицию, обрабатывая исходный материал по особому алгоритму, основанному на использовании случайных чисел.

Вывод случайного изображения


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


Вывод изображения, выбранного случайным образом

Ссылки на изображения хранятся в массиве. Генерируемое случайное число умножается на длину массива (полученную с использованием его свойства length). Полученное число округляется с помощью функции Math.floor() и применяется при установке свойства src элемента img, используемого для вывода изображения. Делается это при загрузке страницы или при нажатии на кнопку.

Случайный фоновый цвет


Здесь можно найти проект, в котором показан случайный выбор фонового цвета.


Случайный выбор фонового цвета

Самое интересное происходит в этом фрагменте кода:

const random = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Эта функция возвращает случайное целочисленное значение из заданного диапазона. Она используется для настройки характеристик цветов, таких, как тон, насыщенность и светлота.

Если вас интересует вопрос случайного генерирования цветов — взгляните на этот материал.

Процедуральное искусство


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


Процедуральное искусство

При построении этих необычных кривых функция Math.random() используется дважды. Первый раз — для выбора цветов градиента. Второй раз — для настройки максимального радиуса кривых. Это — прекрасный пример того, как при каждом запуске процесса создания изображения получается что-то новое.

Случайный выбор слов из заранее созданного списка


Здесь можно найти программу, которая выводит на экран слова, случайным образом выбираемые из заранее созданного массива.


Случайный выбор слов

Вот код, который используется для выбора слова:

var word = words[Math.floor(Math.random() * words.length)] + "!";

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

Генератор ключей API


Вот проект, в котором случайные числа используются для создания ключей API.


Система для создания случайных ключей API

Это — пример использования генератора случайных чисел, имеющий практическое применение в разработке реальных приложений. Здесь для создания UUID (Universally Unique IDentifier, универсальный уникальный идентификатор) программа генерирует 16 случайных чисел. Такой UUID можно использовать в роли ключа для доступа к некоему API.

Вывод фрагментов текста с использованием переходов, сформированных случайными символами


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


Переходы между фразами, сформированные с использованием генератора случайных чисел

Здесь имеются несколько фраз, выводимых друг за другом. Переходы между фразами реализованы с использованием случайных символов, подбираемых с использованием Math.random(). Кажется, что компьютер собирает каждую фразу, выполняя некие таинственные вычисления.

Игра «Камень, ножницы, бумага»


Здесь можно найти реализацию игры «Камень, ножницы, бумага».


Камень, ножницы, бумага

В этой классической игре Math.random() используется в качестве основы игровой логики. Компьютер делает ход, случайным образом выбирая один из трёх вариантов действий.

Генератор надёжных паролей


Вот программа, представляющая собой генератор надёжных паролей.


Генератор надёжных паролей

Здесь Math.random() используется для заполнения массива с будущим паролем буквами в верхнем и нижнем регистрах, цифрами и другими символами. Это — ещё один отличный пример практического использования Math.random().

Заметки о Math.random()


Вполне возможно, что у вас, после того, как вы взглянули на примеры использования Math.random(), возникли вопросы об этой функции. Вот несколько таких вопросов, с которыми мне доводилось встречаться чаще всего.

▍По-настоящему ли случайны числа, которые выдаёт Math.random()?


Они, так сказать, не совсем случайны. Эта функция возвращает псевдослучайные числа. Алгоритм, на котором она основана, называется «генератор псевдослучайных чисел» (Pseudo-Random Number Generator, PRNG). Это значит, что последовательность выдаваемых им чисел может быть, в определённых условиях, воспроизведена.

В частности, работа Math.random() основана на алгоритме xorshift128+, именно его реализация, вероятно, и отвечает в вашем браузере за генерирование случайных чисел.

▍Как получать уникальные значения, в которых отсутствуют повторы?


Есть много методов получения уникальных значений, в последовательности которых отсутствуют повторы. Например, механизм получения таких значений может быть основан на так называемом «тасовании Фишера-Йетса», на алгоритме, направленном на создание случайных перестановок конечных множеств. В следующем примере функция Math.random() используется для «тасования» массива.

function shuffle (array) {
  var i = 0
    , j = 0
    , temp = null

  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1))
    temp = array[i]
    array[i] = array[j]
    array[j] = temp
  }
}

▍Функция Math.random() реализует те же возможности, что и API WebCrypto?


Посмотрев примеры использования Math.random(), вы могли убедиться в том, что это — замечательная функция. Но если вы занимаетесь созданием приложений, работающих с ценной информацией, и вам нужен более надёжный способ генерирования случайных чисел, я посоветовала бы прибегнуть к API WebCrypto. Этот API может пригодиться, например, тем, кому нужно работать с временными кодами проверки пользователей, нужно генерировать случайные пароли, организовывать лотереи.

Если случайные числа вам нужны для использования их в сферах кибербезопасности, криптографии или статистики — пользуйтесь функцией window.crypto.getRandomValues() и посмотрите документацию по API WebCrypto.

Пользуетесь ли вы функцией Math.random() в своих проектах?



RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Comments 15

    +21
    Такое впечатление, что его ещё используют для генерации тем постов на Хабр.
      +15
      Ждём следующую статью по использованию alert().
        0
        А что бы неповадно было копипастить о работе с консолью, оставлю это здесь:
        habr.com/ru/post/114483
        +2

        Учитывая что там внутри xorshift — плохо что не дают явно выставить seed для контролируемой генерации. Из за этого генератор псевдослучайных чисел нужно писать руками, хотя он уже есть !?

          0

          Когда-то был того же мнения, но потом увидел реализацию подбора картинок по хэшам из руби (они в 1.9.4 кажется в патче без изменений номера поменяли агоритм)


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


          П.С.: seedrandom.js

            0
            Из за этого генератор псевдослучайных чисел нужно писать руками, хотя он уже есть !?
            А я так и сделал, «портировал» широко известную хеш-функцию. Производительность по сравнению с нативной почти не изменилась.
            код
            const BJXorShift = (x) => {
              x += x << 10;
              x ^= x >>  6;
              x += x <<  3;
              x ^= x >> 11;
              x += x << 15;
              return x;
            }
            
            let seed = (Math.random() * 0xffffffff) >>> 0;
            const HM = 0x874C40D4 >>> 0;
            ...
            seed = BJXorShift(seed ^ HM);
            

            +2
            Как использовать рандомайзер, это по-моему слишком тривиальная тема… гораздо интереснее было бы узнать об особенностях его JS реализации, и в каком случае его последовательность может быть воспроизведена?
              +2
              Генератор надёжных паролей — это как раз совсем ненадежные пароли и плохой пример использования Math.random()

              Стоит заметить, что раньше по Math.random() можно было определить, что зашел бот Гугла, т.к. выдавал определенную последовательность ПСЧ.
              +1

              минутччччку, а где снежинки?

                0

                Подвис в поисках способа предсказать результаты Math.random() после получения нескольких значений и нашёл. Проверял под Хромом. Только одно значение пропускает, а дальше вроде всё точно. Статья, из неё код на Питоне. В браузере в консоли вводим


                _ = []; for(var i=0; i<5; ++i) { _.push(Math.random()) } ; console.log(_)

                вставляем в строку 147, потом можно повторить генерацию случайных чисел на консоли и запустить питоновский скрипт, смотреть что выдаст. Мне, правда, долго выдавал ошибки про z3 и BitVecs но вот тут рабочее решение онлайн. Первый раз будет долго обновлять библиотеки, в том числе лишние. Без этого никак не запускалось.


                Так что не используйте Math.random() там, где важна непредсказуемость.

                  0

                  Подвис в поисках способа предсказать результаты Math.random() после получения нескольких значений и нашёл. Проверял под Хромом. Только одно значение пропускает, а дальше вроде всё точно. Статья, из неё код на Питоне. В браузере в консоли вводим


                  _ = []; for(var i=0; i<5; ++i) { _.push(Math.random()) } ; console.log(_)

                  вставляем в строку 147, потом можно повторить генерацию случайных чисел на консоли и запустить питоновский скрипт, смотреть что выдаст. Мне, правда, долго выдавал ошибки про z3 и BitVecs но вот тут рабочее решение онлайн. Первый раз будет долго обновлять библиотеки, в том числе лишние. Без этого никак не запускалось.


                  Так что не используйте Math.random() там, где важна непредсказуемость.


                  P.S. Интересно, похоже, в публичной версии другой порядок установки модулей и не работает. В общем, можно там же создать свой аккаунт, скопировать этот файл и подключить последовательно z3, z3-solver и mythril. Ну, или локально поднимать.

                    0
                    Как заголовок «Как получать уникальные значения, в которых отсутствуют повторы?» коррелирует с алгоритмом перемешивания массива? От повторов это не избавляет. И сам вопрос как-будто бы задан совсем о другом.
                      –1
                      механизм получения таких значений может быть основан на так называемом «тасовании Фишера-Йетса»

                      Берем массив со значениями от 0 до 1 000 000, перемешиваем, берем первые 5-10-100 чисел. Хотя статья этого не описывает, да.
                        0
                        Да, так уже понятнее, спасибо. Но в статье, конечно, об этом ничего нет :)

                    Only users with full accounts can post comments. Log in, please.