我知道您可以使用Fisher-Yates Shuffle在JavaScript中对数组进行随机播放。然而,这使用Math.random作为随机数。我想知道你是否可以使用window.crypto.getRandomValues()为随机数源获得更好的 shuffle?
我有一个下面的工作。 getRandomIntInRange()函数使用rejection sampling和示例指定here。
请告诉我这是否是正确的方法,或者如果您能想到更好的方法。 JSFiddle here
$(document).ready(function()
{
var dataArray = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14'];
var shuffledArray = shuffleArray(dataArray);
console.log(shuffledArray);
});
function getRandomIntInRange(min, max) {
var range = max - min + 1;
var maxRange = 256;
var byteArray = new Uint8Array(1);
// Fill byteArray with 1 random number
window.crypto.getRandomValues(byteArray);
// If outside of range, get another
if (byteArray[0] >= Math.floor(maxRange / range) * range)
{
return getRandomIntInRange(min, max);
}
return min + (byteArray[0] % range);
}
function shuffleArray(dataArray) {
var counter = dataArray.length, temp, index;
while (counter > 0)
{
index = getRandomIntInRange(0, counter - 1);
counter--;
temp = dataArray[counter];
dataArray[counter] = dataArray[index];
dataArray[index] = temp;
}
return dataArray;
}
答案 0 :(得分:3)
这段代码没有任何问题(虽然使用数字1到14的字符串似乎毫无意义地缓慢而复杂 - 只有数字1到14有什么问题?)。您当然可以自由使用您喜欢的任何RNG算法。但是,不同的算法被设计为最适合不同的任务。一般来说,为模拟而设计的RNG对于密码学来说是不安全的;加密安全的RNG可用于模拟,但可能太慢。如果你只想玩几款游戏,没问题。但是如果你想要模拟十亿只二十一点或扑克,或者蒙特卡罗与数十亿数据点的集成,那么使用加密RNG可能会使你的代码在几分钟内运行,几周内无法获益。