随机数
2023年02月14日
一、Math.random()
1.1 获取 [n,m]
的随机整数
实现
function getRandomInt(min,max){
return Math.floor(Math.random()*(max-min+1))+min
}
console.log(getRandomInt(2,4));
二、Web Crypto API
2.1 获取 [n,m]
的随机整数
思路:
实现:
-
递归方式
function getRandomInt(min, max) {
const max_range = 1 << 8;
const range = max - min + 1;
const byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray);
if (byteArray[0] >= ((max_range / range) << 0) * range) {
return getRandomInt(min, max);
}
return min + (byteArray[0] % range);
}
const randomInt = getRandomInt(2, 10);
console.log(randomInt); -
迭代方式
function getRandomInt(min, max) {
const max_range = 1 << 8;
const range = max - min + 1;
const byteArray = new Uint8Array(1);
while (true) {
window.crypto.getRandomValues(byteArray);
if (byteArray[0] < ((max_range / range) << 0) * range) {
return min + (byteArray[0] % range);
}
}
}
const randomInt = getRandomInt(2, 10);
console.log(randomInt);
三、Node Crypto API
3.1 获取 [n,m]
的随机整数
实现
const crypto = require("crypto");
function getRandomInt(min, max) {
return crypto.randomInt(min,max+1)
}
console.log(getRandomInt(2, 4));
四、方案对比及问题
4.1 通过 Math.random() 方案获取随机数有什么缺陷? 有什么安全性的问题?
Math.random()
返回的数字是伪随机数。计算机是一种具有确定性的机器, 因此不可能产生真正的随机数。伪随机数生成器(PRNG
)近似于随机算法,始于一个能计算后续数值的种子。
PRNG
包括两种类型: **统计学的PRNG
**和密码学的PRNG
。
-
**统计学的
PRNG
**提供了很多有用的统计属性,输出结果很容易预测,因此容易复制数值流。在对安全性要求较高的环境中, 使用能够生成可预测值的函数作为随机数据源, 会产生Insecure Randomness
错误。Math.random
就是统计学的PRNG
,攻击者很容易猜到其生成的字符串。因此,Math.random
这种伪随机数生成器可以快速的计算出看起来很随机的数值,但是不使用用于加密计算。 -
密码学的
PRNG
生成的输出结果很难预测,可解决这一问题。可以解决可预测值的问题, 保证了值的加密安全。因此, 密码学PRNG
计算随机数的速度虽然慢了许多,但是生成的值很难预测, 可以用于加密。