背景
周中有空,有空安排设计了一个开发猜数字的游戏,代码如下面的内容,简简单单可以轻松娱乐一下,发给了公司的同事看看,没想到被问到下面的问题,让我产生了深思,生成随机数的方法 Math.random
方法 到底是 如何设置随机种子的呢?
这里我们有两个点
- 随机种子到底是什么呢?(前端一般没有随机种子的概念)
Math.random
底层的原理是什么呢,它里面的逻辑是怎么样的
游戏代码
js
const key = Math.floor(Math.random() * 100 + 1)
let guess = 0
let count = 1
guess = parseInt(prompt('欢迎来到<猜数字>游戏,请在七次内找到 1-100 中记录的随机数'))
if (guess) {
while (count < 7) {
if (guess > key) {
guess = parseInt(prompt(`您猜的数字大了,还剩${7 - count}次`))
} else if (guess < key) {
guess = parseInt(prompt(`您猜的数字小了,还剩${7 - count}次`))
} else {
prompt('恭喜 您猜对了!!!', `您用了${count}次数猜中 按 enter 键退出`)
break
}
count++
}
} else {
alert('退出游戏')
}
随机种子到底是什么?它在前端中有什么应用场景呢?
随机种子(Random Seed)是一个初始值,通常是一个数字,用于初始化随机数生成器。这个种子值可以影响随机数生成器生成的随机数序列。
在前端开发中,随机种子通常与随机数生成相关,有以下应用场景和作用:
-
伪随机数生成:计算机上的随机数生成实际上是伪随机的,因为它们是通过算法生成的。这意味着如果你使用相同的随机种子,你将获得相同的随机数序列。这对于模拟、测试和可重复的实验非常有用。
-
数据随机化:在前端开发中,你可能需要在网页上生成随机数据,例如随机展示广告、随机排序列表项、或者在游戏中创建随机关卡。通过指定相同的随机种子,你可以确保用户每次访问网页时都看到相同的随机数据,以提供一致的体验。
-
数据加密和哈希:在前端的安全应用中,随机种子可以用于加密和哈希算法。例如,随机种子可以用于生成加密密钥,以增加安全性。
-
游戏开发:在游戏开发中,随机种子用于创建游戏中的随机性元素,如地图生成、敌人行为、随机事件等。通过使用相同的随机种子,你可以确保在多次游戏会话中获得相同的游戏体验。
-
数据生成和测试:在单元测试、性能测试和模拟环境中,使用随机种子可以生成可预测的测试数据,以便更轻松地验证应用程序的行为。
需要注意的是,随机种子不应该是公开的或容易猜测的值,因为它可以影响生成的随机性。
通常,随机种子应该是足够复杂和难以预测的,以确保生成的随机数序列是相对安全的。在前端开发中,JavaScript提供Math.random()
函数,但它不允许你指定种子值。如果需要更精确的控制,可以考虑使用第三方库或自定义函数来生成随机数并设置种子。如果在项目中的 随机种子是公开的,这样随机数序列将会不再安全了。
Math Random 方法背后逻辑
Math.random()
是JavaScript中用于生成伪随机浮点数的方法。这个方法返回一个大于或等于0且小于1的随机小数,包括0但不包括1。背后的逻辑涉及伪随机数生成器。这个背后的逻辑其实也是通过查阅第三方的资料我才知道的(算是涨知识了)
具体的逻辑如下:
-
伪随机数生成器:
Math.random()
使用伪随机数生成器(Pseudo-Random Number Generator,PRNG)来生成随机数。这是一种算法,它以一个种子值为输入,并在每次调用时输出一个看似随机的数字。由于PRNG是基于算法的,它实际上并不是真正的随机,而是根据初始种子生成的伪随机数序列。 -
种子值:在JavaScript中,
Math.random()
不要求你提供种子值,它使用内部时钟时间戳等作为默认种子值。这意味着,如果你多次连续调用Math.random()
,它会生成不同的随机数序列,因为时间戳不断变化。 -
随机数范围:
Math.random()
生成的随机数范围是[0, 1),这意味着它可以生成0,但不能生成1。如果需要在其他范围内生成随机整数或浮点数,你可以通过一些数学运算将其映射到你需要的范围。
示例:
javascript
// 生成一个随机浮点数(大于等于0,小于1)
var randomNumber = Math.random();
// 生成一个随机整数(在0到9之间)
var randomInteger = Math.floor(Math.random() * 10);
// 生成一个随机整数(在1到6之间,模拟骰子)
var diceRoll = Math.floor(Math.random() * 6) + 1;
需要注意的是,由于Math.random()
是伪随机数生成器,它不适合用于需要高度随机性和安全性的场景,如密码生成。在这些情况下,应使用更强大的随机数生成库。
第三方的 随机数生成工具推荐
当涉及到生成伪随机数并控制随机数生成的种子时,以下是一些常用的第三方库和工具,适用于前端开发:
- Seedrandom : 这是一个小巧且强大的库,它允许你设置随机数生成的种子。你可以使用它来生成随机数,确保相同种子生成相同的随机序列。它可以用于浏览器和 Node.js环境。GitHub链接:github.com/davidbau/se...
- Random.js : Random.js 是一个面向浏览器的JavaScript库,它提供了高度可控的伪随机数生成,包括设置种子、生成随机整数和浮点数等功能。GitHub链接:github.com/ckknight/ra...
- Chance.js : Chance.js 是一个用于生成随机数据的库,包括随机数、日期、颜色、姓名等。它可以设置种子以重现相同的随机数据。这对于模拟数据在开发和测试中非常有用。GitHub链接:github.com/chancejs/ch...
- Math.js : Math.js 一个全功能的数学库,它包括随机数生成功能。虽然它主要用于数学计算,但也可以用于生成随机数。GitHub链接:github.com/josdejong/m...
第三方库的逻辑
一般不提供种子的话,会随机会创建一个基于 ARC4
的 PRNG
作为随机种子
通过传入 Key 值 让 ARC4
值变得可控
详细可以看第三方库是如何实现 Random
随机种子实现的,这里就不过多的叙述了
总结
简单生成一个随机数功能,我开始的时候是没想到里面竟然有这么多的学问,原来背后的逻辑是这么复杂的。如果这篇文章帮到你的话,王可以给我点一个赞,这对我来说真的十分重要,谢谢大家。