[06天]JS 随机数与UUID

常用随机数代码

生成JS随机数:

Math.random().toString().replace('0.', '')


数组随机排序:

[1, 2, 3, 4, 5].sort(_ => Math.random() - 0.5)


随机取a到b之间的一个整数

function br(a, b) {
    return Math.random()*(b-a+1)+a|0
}


深入讨论Math.random

Math.random的安全风险

为了保证足够的性能,Math.random() 随机数并不是实时生成的,而是直接生成一组随机数(64个),并放在缓存中。  当这一组随机数取完之后再重新生成一批,放在缓存中

由于 Math.random() 的底层算法是公开的(xorshift128+ 算法),V8 源码可见,因此,是可以使用其他语言模拟的,这就导致,如果攻击者知道了当前随机生成器的状态,那就可以知道缓存中的所有随机数,那就很容易匹配与破解。  例如抽奖活动,使用 Math.random() 进行随机,那么就可以估算出一段时间内所有的中奖结果,从而带来非常严重且致命的损失。


更安全的getRandomValues方法

方法让你可以获取符合密码学要求的安全的随机值。传入参数的数组被随机值填充(在加密意义上的随机)

getRandomValues() 方法的随机种子生成器更加的无序,例如系统层面的无序源(有些硬件自带随机种子)。以及 getRandomValues() 方法的底层实现是没有缓存的,随机数都是实时生成的

使用示例:

let randNumber = crypto.getRandomValues(new Uint32Array(1))[0];// 一串随机整数,通常10位
console.log(randNumber);


JS原生生成UUID(支持:Chrome 92+)

/* Assuming that self.crypto.randomUUID() is available */
let uuid = self.crypto.randomUUID();
console.log(uuid); // for example "36b8f84d-df4e-4d49-b662-bcde71a8764f"


Math.random与Crypto.randomUUID

日常开发开始推荐使用 Math.random() 方法,高性能且实用,

但是如果我们的随机值与加密相关,或者涉及到金钱等安全性要求非常高的场景,务必使用 getRandomValues() 方法

至于Crypto.randomUUID()方法,视浏览器支持环境甚用。


更多实用随机代码

从字符串chars中返回指定长度n随机字符串

const chars = [
      '0','1','2','3','4','5','6','7','8','9',
      'A','B','C','D','E','F','G','H','I','J',
      'K','L','M','N','O','P','Q','R','S','T',
      'U','V','W','X','Y','Z'
];
function generateMixed(n, chars) {
      var res = "";
      for(var i = 0; i < n ; i ++) {
            var index = Math.ceil(Math.random()*chars.length);
            res += chars[index];
      }
      return res;
}


从指定数组中随机抽取一个成员

const users = ['lenton', 'tom', 'gina', 'maxs']
function (items) {
    return items[Math.floor((Math.random()*items.length))]
}


从指定数组中随机抽取n个成员且不能重复

function getArrayItems(arr, n) {
    const tempArray = [...arr]
    const resArray = []
    for (let i = 0; i< n; i++) {
        if (tempArray.length > 0) {
            const arrIndex = Math.floor(Math.random()*tempArray.length)
            resArray[i] = tempArray[arrIndex]
            tempArray.splice(arrIndex, 1)
        } else {
            break
        }
    }
    return resArray
}

const res = getArrayItems([1,2,3,4,5,6,7,8,9], 3)
console.log(res)



参考文章:

鑫空间-鑫生活 https://www.zhangxinxu.com/wordpress/2021/12/js-getrandomvalue-math-random/

MDN https://developer.mozilla.org/zh-CN/docs/Web/API/Crypto/getRandomValues

MDNhttps://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID


2022-05-22 16:47:45 950 0

参与讨论

选择你的头像