[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的安全风险
为了保证足够的性能,
随机数并不是实时生成的,而是直接生成一组随机数(64个),并放在缓存中。 当这一组随机数取完之后再重新生成一批,放在缓存中
Math.random()
由于
的底层算法是公开的(xorshift128+ 算法),V8 源码可见,因此,是可以使用其他语言模拟的,这就导致,如果攻击者知道了当前随机生成器的状态,那就可以知道缓存中的所有随机数,那就很容易匹配与破解。 例如抽奖活动,使用 Math.random() 进行随机,那么就可以估算出一段时间内所有的中奖结果,从而带来非常严重且致命的损失。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
参与讨论