Случайное число: Math.random и целое в диапазоне
Целое число от min до max включительно:
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 6));Каждый запуск выводит своё число от 1 до 6, как бросок кубика.
Как это работает
Math.random() возвращает дробное число от 0 (включительно) до 1 (не включая 1): например, 0.7316….
Math.random() * (max - min + 1)растягивает его до диапазона от 0 до 6 (не включая 6) для кубика.Math.floorотбрасывает дробную часть: получаются целые 0, 1, 2, 3, 4, 5 — с равными шансами.+ minсдвигает диапазон: 1, 2, 3, 4, 5, 6.
Проверка: десять тысяч бросков дают все шесть значений и ни одного лишнего:
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const seen = new Set();
for (let i = 0; i < 10000; i++) {
seen.add(randomInt(1, 6));
}
console.log([...seen].sort((a, b) => a - b));[ 1, 2, 3, 4, 5, 6 ]Set — набор без повторов: в нём остаются только разные выпавшие числа.
Частые ошибки
Math.roundвместоMath.floor.Math.round(Math.random() * 5) + 1тоже даёт числа от 1 до 6, но крайние, 1 и 6, выпадают вдвое реже остальных.- Забытое
+ 1.Math.floor(Math.random() * 6)даёт числа от 0 до 5, а не от 1 до 6. - Дробное число от a до b — это
Math.random() * (b - a) + a, безMath.floor.
Случайный элемент массива
const colors = ["красный", "зелёный", "синий"];
const color = colors[Math.floor(Math.random() * colors.length)];
console.log(color);Перемешать массив
Надёжный способ — алгоритм Фишера — Йейтса: идти с конца и менять каждый элемент местами со случайным из ещё не тронутых:
function shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
console.log(shuffle([1, 2, 3, 4, 5]));Популярная короткая запись array.sort(() => Math.random() - 0.5) перемешивает неравномерно: одни порядки выпадают заметно чаще других.
Пароли, коды и токены
Math.random() не годится там, где случайность защищает: пароли, коды подтверждения, ключи. Его значения можно предсказать. Для этого есть криптографический генератор:
// в браузере
const array = new Uint32Array(1);
crypto.getRandomValues(array);
console.log(array[0]);// в Node.js: целое от 100000 до 999999 включительно (верхняя граница не входит)
const { randomInt } = require("node:crypto");
console.log(randomInt(100000, 1000000));Во втором примере — шестизначный код подтверждения. У randomInt из node:crypto верхняя граница, в отличие от функции выше, в диапазон не входит.