稀土掘金 稀土掘金

为什么不建议使用 Math.random 生成随机数

本文正在参加 「金石计划 . 瓜分6万现金大奖」

前言

日常开发中大家经常使用 Math.random 来实现随机的效果,但是你知道 Math.random 实际上是“伪随机”吗?除了 Math.random 外,有什么方式可以实现真随机的?大家可以带着这些疑问继续阅读。

Math.random

介绍

Math.random()  函数返回一个浮点数,伪随机数在范围从0 到小于1,也就是说,从 0(包括 0)往上,但是不包括 1(排除 1),然后您可以缩放到所需的范围。

语法

Math.random()

返回值

返回一个浮点型伪随机数字,在0(包括 0)和1(不包括)之间。

Mat为.random 真的随机吗

我们可以简单测试一下 Math.random 生成数字的分布概率。这里我们可以使用一个数组来进行统计:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const locationMap = new Array(10).fill(0);

const shuffle = (nums) => {
    const lens = nums.length;
    nums.sort(() => Math.random() - 0.5);
    locationMap[nums[lens - 1] - 1]++;
}

for (let i = 0; i < 100000; ++i) {
    shuffle(arr.slice());
}

console.log(locationMap);

log:
[
  10199, 2629,  8036,
   7046, 9260, 12724,
  16780, 9567, 10967,
  12792
]

我们可以看出元素在各个位置出现的概率差距有可能是巨大的。因此通过 Math.random 打乱的数组并不是真正的随机。

我们还可以从这引申出另一个问题:很多面试题合集里会有打乱数组这么一道题,大部分题解用的都是 nums.sort(() => Math.random() - 0.5) 这个手段去实现“随机”打乱的,如果面试官好说话倒还好,如果面试官有意刁难,小伙伴们有办法写出真正随机的打乱数组方法吗?

为了做到真随机打乱数组,我们首先要做到元素在各个位置的出现的概率是一样或者近似的。

洗牌算法

洗牌算法的步骤就是将数组分为 未排序区域 和 已排序区域,不断的从未排序区域中 随机 出一个下标来,和未排序区域的最后一个元素 交换 ,进行 n 轮交换后就实现了等概率的洗牌算法了。

const shuffle = (arr) => {
    const lens = arr.length;
    for (let i = 0; i < lens; ++i) {
        const idx = Math.floor(Math.random() * (lens - i));
        [arr[idx], arr[lens - i - 1]] = [arr[lens - i - 1], arr[idx]];
    }
    return arr;
}

const arr = [6, 10, 4, 2, 7];
console.log(shuffle(arr));

由于洗牌算法不是本文的重点,这里就简单介绍一下。

crypto.getRandomValues

介绍

crypto.getRandomValues 方法让你可以获取 符合密码学要求的安全的随机值 。传入参数的数组被随机值填充。

语法

cryptoObj.getRandomValues(typedArray);

示例

/* 假设 window.crypto.getRandomValues 可用 */

var array = new Uint32Array(1);
window.crypto.getRandomValues(array);

我们看看输出:

微信截图_20221109201006.png

封装函数

接下来我们封装一个获取随机数的方法:

const myRandom = function (){
  const array = new Uint32Array(1);
  const randomNum = crypto.getRandomValues(array)[0] / 0xffffffff;
  return `${randomNum}`[2];
}

结束语

如果小伙伴们有别的想法,欢迎留言,让我们共同学习进步💪💪。

如果文中有不对的地方,或是大家有不同的见解,欢迎指出🙏🙏。

如果大家觉得所有收获,欢迎一键三连💕💕。

玻璃钢生产厂家畅销的玻璃钢卡通雕塑闵行区通用玻璃钢雕塑便宜舟山多彩玻璃钢雕塑市场洛阳玻璃钢雕塑设计西湖玻璃钢造型雕塑商场美陈 布艺成品玻璃钢雕塑摆件研发宜春玻璃钢雕塑销售厂家玻璃钢浮雕铜雕塑定做山东火烈鸟玻璃钢雕塑定制聊城电镀玻璃钢雕塑制作太原玻璃钢人物雕塑厂家青浦区玻璃钢雕塑优选企业云浮玻璃钢人物雕塑手工制作江苏黑色玻璃钢花盆贵阳商场美陈展览福建室内商场美陈销售公司玻璃钢花盆简笔画动物奥体元旦商场美陈特色商场美陈市场浦口商场主题美陈兴义玻璃钢雕塑公司卡通人玻璃钢雕塑摆件研发公司商场春季美陈图片金昌景区玻璃钢雕塑玻璃钢雕塑模具定做厂家玻璃钢孔子雕塑报价玻璃钢雕塑今日行情上海室内商场美陈销售企业平顶山苏州玻璃钢人物雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化