我被引导到这个问题作为使用以下关键字的顶级搜索引擎结果:
- 安全随机范围 js
- securerandom js
因此,我认为用今天(2019 年)可用的有效答案更新这篇文章会很好:
下面的 sn-p 使用 Crypto.getRandomValues() 来获取据说是的随机值,
...密码学强...使用伪随机数生成器播种具有足够熵的值...适合加密使用。
因此,我们有:
var N = 32;
var rng = window.crypto || window.msCrypto;
var rawBytes = Array
.from(rng.getRandomValues(new Uint8Array(N)))
.map(c => String.fromCharCode(c))
.join([]);
现在,下面是一个有趣的小十六进制编码器,我使用一些 Array 函数进行循环:
function hexEncode(s) {
return s.split('').map(c => (c < String.fromCharCode(16) ? '0' : '') + c.charCodeAt(0).toString(16)).join([]);
}
最后,如果你想结合上面的两个来生成随机哈希,你可以换出并相应地调整.map()函数并像这样打包它:
function secureRandomHash(N) {
N = N || 32; // Coalesce if size parameter N is left undefined
// TODO: Consider refactoring with lazy-loaded function
// to set preferred RNG provider, else throw an error here
// to generate noise that no secure RNG is available for
// this application.
var rng = window.crypto || window.msCrypto;
return Array
.from(rng.getRandomValues(new Uint8Array(N)))
.map(c => (c < 16 ? '0' : '') + c.toString(16)).join([]);
}
编码愉快!
编辑:结果我最终在我自己的项目中需要这个,它也实现了前面示例中建议的 TODO(延迟加载)所以我们开始吧:
Math.secureRandom = function() {
var rng = window.crypto || window.msCrypto;
if (rng === undefined)
throw 'No suitable RNG found';
// Lazy-load this if- branch
Math.secureRandom = function() {
// More secure implementation of Math.random (https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples)
return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
};
return Math.secureRandom();
}
或者如果你真的很喜欢冒险......
// Auto-upgrade Math.random with a more secure implementation only if crypto is available
(function() {
var rng = window.crypto || window.msCrypto;
if (rng === undefined)
return;
// Source: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#Examples
Math.random = function() {
return rng.getRandomValues(new Uint32Array(1))[0] / 4294967296;
};
})();
console.log(Math.random());
扩展Math 或覆盖Math.random() 是否适合您的应用程序或目标受众,这纯粹是实施者的学术练习。请务必先咨询您的建筑师!当然在这里获得 MIT 许可 :)