死灵术。
嗯,这很容易解决。
考虑没有加密随机范围内的随机数:
// 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;
}
所以你需要做的就是用 crypt 中的随机数替换 Math.random。
那么 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) 以确保结果 < 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 来获取随机字节,则不应将这些值视为真正加密安全的熵源。