提起随机数,大家的第一反应一般是Math.random。然而, ECMAScript里面(中文版见 这里)并没有规定用什么算法来实现这个API,只是规定了生成的数字应该在[0, 1)内近似均匀分布。这就使得很多引擎实现在实现时采用了比较简单地算法,并不保证随机数的不可预测。
这样的随机数显然不能用于数据加密。那么,有什么API可以获得一个安全的随机数呢?

如果是Node.js,你可以使用 crypto.randomBytes(size[, callback])这个API,比如下面的code获得了一个包含4个byte的随机数:

1
2
3
4
5
crypto.randomBytes(4, function(err, buf){
if (err) return;
console.log(buf.length);
console.log(buf[0], buf[1], buf[2], buf[3]);
});

那浏览器端怎么办呢,你可以使用 crypto.getRandomValues(array)这个API,现在很多浏览器都支持这个API了(具体浏览器支持情况请见 这里),比如下面的code获得了一个Uint32(4个byte)的随机数:

1
2
3
var buffer = new Uint32Array(1);
crypto.getRandomValues(buffer);
console.log(buffer[0]);

搞定,收工!