当前位置: 首页 > Web前端 > JavaScript

更安全的随机数生成

时间:2023-03-27 02:14:11 JavaScript

Math.random()通常我们使用Math.random()来生成伪随机数,在大多数情况下可以方便的使用。例如生成混合随机字符Math.random().toString(36).substr(2);生成一个随机数constrandomNumber=(min,max)=>Math.floor(Math.random()*(max-min)+min);但是如果Math.random()在一些比较严谨的场景下随机分布不够均匀,可以使用比较安全的随机数生成接口基本的密码学操作界面。它提供了一个随机数生成方法getRandomValues。Math.random()的随机数分布是不够的。虽然大多数情况下不会发生冲突,但确实存在隐患。而且getRandomValues的兼容性还是不错的。生成随机数首先需要提供一个TypedArray对象,生成的随机数会覆盖其中的对象。window.crypto.getRandomValues(newUint32Array(5))Crypto.getRandomValues()还是比较原始直接使用还是需要重新处理数据。网上还有一个可以直接使用的生成代码:生成[0,1)之间的随机数(与Math.random()一致)constcryptoRand=()=>{constrandomBuffer=newUint32Array(1);window.crypto.getRandomValues(randomBuffer);返回(randomBuffer[0]/(0xffffffff+1));//0xFFFFFFFF=uint32.MaxValue(+1因为Math.random包含0,但不包含1)}生成指定范围内的随机数constrandomNumber=(min,max)=>{constrandomBuffer=newUint32Array(1);window.crypto.getRandomValues(randomBuffer);constnumber=randomBuffer[0]/(0xffffffff+1);返回Math.floor(number*(max-min)+min);}生成IDconstgenerateId=(len)=>{consttypeArray=newUint8Array((len||40)/2)window.crypto.getRandomValues(typeArray)returnArray.from(typeArray,dec=>dec.toString(16).padStart(2,"0")).join('')}或constuuidv4=()=>([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,c=>(c^加密。getRandomValues(newUint8Array(1))[0]&15>>c/4).toString(16));需要注意的是,为了性能crypto.getRandomValues生成随机数时并没有真正的随机数生成器,而是使用了一个具有足够熵的伪随机数生成器。如果需要加密场景,用户需要提供足够熵源的种子。或者使用现成的随机数生成库nanoid。NanoIDNanoID是一个小型、安全、URL友好、独特的JavaScript字符串ID生成器。浏览器支持,Node.js、ReactNative和其他各种语言都可用。安装npminstall--savenanoid以安全地生成随机数:synchronousimport{nanoid}from'nanoid'model.id=nanoid()//=>"V1StGXR8_Z5jdHi6B-myT"asynchronousimport{nanoid}from'nanoid/async'awaitnanoid()如果你更关心性能,你可以降低安全性使用非安全的随机数生成器import{nanoid}from'nanoid/non-secure'constid=nanoid()//=>"Uakgb_J5m9g-0JDMbcJqLJ"当然也可以自定义随机字符和大小,具体方法可以查看文档。相关信息MDN-Math.random()MDN-Crypto.getRandomValues()NanoID文档Math.random()ThingsRandomNumberGenerationinJavaScript