Node.js 节点:使用crypto.randomBytes生成6位随机数
既然Node.js 节点:使用crypto.randomBytes生成6位随机数,node.js,algorithm,cryptography,Node.js,Algorithm,Cryptography,既然1000000不是2的幂,那么从0到999999随机生成精确值的正确方法是什么 这是我的方法: private generateCode(): string { let code: string = ""; do { code += randomBytes(3).readUIntBE(0, 3); // code += Number.parseInt(randomBytes(3).toString("hex"), 16); } whi
1000000
不是2的幂,那么从0
到999999
随机生成精确值的正确方法是什么
这是我的方法:
private generateCode(): string {
let code: string = "";
do {
code += randomBytes(3).readUIntBE(0, 3);
// code += Number.parseInt(randomBytes(3).toString("hex"), 16);
} while (code.length < 6);
return code.slice(0, 6);
}
crypto.randomBytes
生成3个字节并转换为hex
fffff
==1048575
99999
)999999
,请再次从步骤1开始它将以某种方式创建一个递归函数。它是逻辑正确的,它会引起性能的关注吗?< P>这是一个正确的算法(),尽管您可以考虑使用位操作而不是转换为十六进制。如果随机数生成器出现故障,它可以永远运行——你可以考虑尝试一个固定的次数,然后抛出一个异常而不是循环循环。 < P>主要的性能问题是,在一些平台上,<代码>密码。所以如果你使用它,你不想浪费任何随机性 因此,我将使用以下整数操作来代替字符串比较
if (random_bytes < 16700000) {
return random_bytes = random_bytes - 100000 * Math.floor(random_bytes/100000);
}
if(随机字节<16700000){
返回random\u bytes=random\u bytes-100000*数学地板(random\u bytes/100000);
}
这大约有99.54%的几率从前3个字节中生成答案,而您的方法的几率约为76%。有几种方法可以从随机位中提取一定范围内的随机数。中描述了一些常见的问题 尽管本标准是关于确定性随机位生成的,但有一个名为a.5将随机位转换为随机数的有用附录,其中描述了三种有用的方法 所述方法包括:
- A.5.1简单丢弃方法
- A.5.2复杂废弃方法
- A.5.3简单模块化方法
我自己也想到了一种基于简单丢弃方法的非常有效的算法,称为“BC”代表“二进制比较”。这是基于这样的观察:比较只关注最高有效位,这意味着最低有效位仍应被视为随机的,因此可以重用。请注意,该方法尚未经过正式同行评审;我确实用简单的丢弃方法给出了一个非正式的等价性证明
当然,如果给定
N
的任何值,您应该使用有效的通用方法。在这种情况下,应将复杂丢弃方法或简单模块化方法置于简单丢弃方法之上。还有其他更复杂的算法更有效,但通常使用这两种算法中的任何一种都可以
注意,当在范围
[0,N)
。如果N
是二的幂,则无需使用这些可能昂贵的计算;只需使用随机位或字节生成器中所需的位。我建议以下方法:
private generateCode(): string {
let code: string = "";
do {
code += randomBytes(3).readUIntBE(0, 3);
// code += Number.parseInt(randomBytes(3).toString("hex"), 16);
} while (code.length < 6);
return code.slice(0, 6);
}
private generateCode():字符串{
let代码:string=“”;
做{
code+=randomBytes(3)。readUIntBE(0,3);
//code+=Number.parseInt(随机字节(3).toString(“十六进制”),16);
}而(代码长度<6);
返回码.切片(0,6);
}
这将以字符串形式返回数字代码,但如果需要将其作为数字,则将其更改为
返回number.parseInt(code.slice(0,6))
我将其称为随机算法。最坏情况下,只需一个附加循环
var random_6d=函数(n2){
var n1=加密随机字节(3).readUIntLE(0,3)>>>4;
如果(n1<1000000)
返回n1;
如果(类型n2==‘未定义’)
返回随机_6d(n1);
返回数学绝对值(n1-n2);
};
循环版本:
var random_6d=函数(){
变种n1,n2;
while(true){
n1=加密随机字节(3).readUIntLE(0,3)>>>4;
如果(n1<1000000)
返回n1;
如果(类型n2==‘未定义’)
n2=n1;
其他的
返回数学绝对值(n1-n2);
};
};
Math.floor(Math.random(1000000)*1000000)我知道,但是Math.random
不是加密安全的。我的问题是使用crypto.randomBytes
你可以计算出分数YourRandInt/maxmaxpability
并将其与你想要的范围相乘(999.999),然后四舍五入到下一个整数。我不确定这是否会更频繁地产生某些数字。@TobiasK,谢谢,但是我认为这种方法与使用模运算的YourRandInt%1000000相同,使用模运算有x2的机会得到0到48575之间的值,我认为使用这种方法确实不会发生这种情况,因为每个Yo