死灵术。
嗯,这很容易解决。
考虑random number in ranges without crypto-random:
// Returns a random number between min (inclusive) and max (exclusive)
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
/**
* Returns a random integer between min (inclusive) and max (inclusive).
* The value is no lower than min (or the next integer greater than min
* if min isn't an integer) and no greater than max (or the next integer
* lower than max if max isn't an integer).
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
所以您需要做的就是将 Math.random 替换为来自 crypt 的随机数。
那么 Math.random 做了什么?
根据MDN,Math.random() 函数返回一个浮点伪随机数,范围为 0 到小于 1(包括 0,但不包括 1)
所以我们需要一个加密随机数 >= 0 和 1(不是 )。
因此,我们需要一个来自 getRandomValues 的 非负(又名 UNSIGNED)整数。
我们如何做到这一点?
简单:
我们没有得到一个整数,然后执行 Math.abs,而是得到一个 UInt:
var randomBuffer = new Int8Array(4); // Int8Array = byte, 1 int = 4 byte = 32 bit
window.crypto.getRandomValues(randomBuffer);
var dataView = new DataView(array.buffer);
var uint = dataView.getUint32();
它的简写版本是
var randomBuffer = new Uint32Array(1);
(window.crypto || window.msCrypto).getRandomValues(randomBuffer);
var uint = randomBuffer[0];
现在我们需要做的就是将 uint 除以 uint32.MaxValue(又名 0xFFFFFFFF)得到一个浮点数。而且因为我们不能在结果集中有 1,所以我们需要除以 (uint32.MaxValue+1) 以确保结果为
除以 (UInt32.MaxValue + 1) 有效,因为 JavaScript 整数在内部是 64 位浮点数,因此不限于 32 位。
function cryptoRand()
{
var array = new Int8Array(4);
(window.crypto || window.msCrypto).getRandomValues(array);
var dataView = new DataView(array.buffer);
var uint = dataView.getUint32();
var f = uint / (0xffffffff + 1); // 0xFFFFFFFF = uint32.MaxValue (+1 because Math.random is inclusive of 0, but not 1)
return f;
}
它的简写是
function cryptoRand()
{
const randomBuffer = new Uint32Array(1);
(window.crypto || window.msCrypto).getRandomValues(randomBuffer);
return ( randomBuffer[0] / (0xffffffff + 1) );
}
现在您需要做的就是将上述函数中的 Math.random() 替换为 cryptoRand()。
请注意,如果 crypto.getRandomValues 使用 Windows 上的 Windows-CryptoAPI 来获取随机字节,you should not consider these values a truly cryptographically secure source of entropy.