首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Node.js -如何使用crypto.randomBytes在特定范围内生成随机数

问Node.js -如何使用crypto.randomBytes在特定范围内生成随机数
EN

Stack Overflow用户
提问于 2015-11-09 12:44:59
回答 5查看 52.6K关注 0票数 18

如何使用crypto.randomBytes在特定范围内生成随机数?

我希望能够生成这样的随机数:

代码语言:javascript
复制
console.log(random(55, 956)); // where 55 is minimum and 956 is maximum

我被限制使用crypto.randomBytes只在随机函数中生成这个范围内的随机数。

我知道如何将生成的字节从randomBytes转换为十六进制或十进制,但我不知道如何从数学上从随机字节得到特定范围内的随机数。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-11-10 10:01:01

感谢@Mustafamg的回答和@CodesInChaos的巨大帮助,我设法解决了这个问题。我做了一些调整,增加幅度最大256^6-1或281,474,976,710,655.范围可以增加更多,但您需要为大整数使用额外的库,因为256^7-1超出了Number.MAX_SAFE_INTEGER限制。

如果有人有同样的问题,可以随意使用。

​

代码语言:javascript
复制
var crypto = require('crypto');

/*
Generating random numbers in specific range using crypto.randomBytes from crypto library
Maximum available range is 281474976710655 or 256^6-1
Maximum number for range must be equal or less than Number.MAX_SAFE_INTEGER (usually 9007199254740991)
Usage examples:
cryptoRandomNumber(0, 350);
cryptoRandomNumber(556, 1250425);
cryptoRandomNumber(0, 281474976710655);
cryptoRandomNumber((Number.MAX_SAFE_INTEGER-281474976710655), Number.MAX_SAFE_INTEGER);

Tested and working on 64bit Windows and Unix operation systems.
*/

function cryptoRandomNumber(minimum, maximum){
	var distance = maximum-minimum;
	
	if(minimum>=maximum){
		console.log('Minimum number should be less than maximum');
		return false;
	} else if(distance>281474976710655){
		console.log('You can not get all possible random numbers if range is greater than 256^6-1');
		return false;
	} else if(maximum>Number.MAX_SAFE_INTEGER){
		console.log('Maximum number should be safe integer limit');
		return false;
	} else {
		var maxBytes = 6;
		var maxDec = 281474976710656;
		
		// To avoid huge mathematical operations and increase function performance for small ranges, you can uncomment following script
		/*
		if(distance<256){
			maxBytes = 1;
			maxDec = 256;
		} else if(distance<65536){
			maxBytes = 2;
			maxDec = 65536;
		} else if(distance<16777216){
			maxBytes = 3;
			maxDec = 16777216;
		} else if(distance<4294967296){
			maxBytes = 4;
			maxDec = 4294967296;
		} else if(distance<1099511627776){
			maxBytes = 4;
			maxDec = 1099511627776;
		}
		*/
		
		var randbytes = parseInt(crypto.randomBytes(maxBytes).toString('hex'), 16);
		var result = Math.floor(randbytes/maxDec*(maximum-minimum+1)+minimum);
		
		if(result>maximum){
			result = maximum;
		}
		return result;
	}
}

​

到目前为止,它运行良好,您可以使用它作为非常好的随机数生成器,但我严格地不建议在任何加密服务中使用该函数。如果你愿意的话,你可以冒险使用它。

欢迎所有的评论,建议和批评!

票数 5
EN

Stack Overflow用户

发布于 2015-11-09 13:22:10

要在一定范围内生成随机数,可以使用以下公式

代码语言:javascript
复制
Math.random() * (high - low) + low

但是您希望使用crypto.randomBytes而不是Math.random(),这个函数返回一个带有随机生成字节的缓冲区。反过来,您需要将此函数的结果从字节转换为十进制。这可以使用biguint格式的包来完成。要安装此软件包,只需使用以下命令:

代码语言:javascript
复制
npm install biguint-format --save

现在您需要将crypto.randomBytes的结果转换为十进制,您可以这样做:

代码语言:javascript
复制
var x= crypto.randomBytes(1);
return format(x, 'dec');

现在您可以创建随机函数,如下所示:

代码语言:javascript
复制
var crypto = require('crypto'),
    format = require('biguint-format');

function randomC (qty) {
    var x= crypto.randomBytes(qty);
    return format(x, 'dec');
}
function random (low, high) {
    return randomC(4)/Math.pow(2,4*8-1) * (high - low) + low;
}
console.log(random(50,1000));
票数 26
EN

Stack Overflow用户

发布于 2015-11-09 13:09:05

以生成范围在55 .956,首先在0范围内生成一个随机数。901,其中901 =956-55。然后把55加到你刚刚生成的数字上。

在0范围内生成一个数字。901,选择两个随机字节并屏蔽6位。这会给你一个在0范围内的10位随机数。1023.如果这个数字是<= 901,那么您就完成了。如果它大于901,则丢弃它,再得到两个随机字节。不要试图使用MOD,使数字进入正确的范围,这将扭曲输出,使其非随机。

ETA:减少不得不丢弃生成的数字的机会。

因为我们从RNG中取了两个字节,所以我们得到了0范围内的一个数字..65535。现在65535 MOD 902是591。因此,如果我们的两个字节随机数小于(65535 - 591),即小于64944,我们可以安全地使用MOD运算符,因为每个数字在0范围内。901现在也同样有可能。任何两个字节的数字>= 64944仍然必须被丢弃,因为使用它会使输出偏离随机。以前,不得不拒绝一个数字的机会是(1024-901)/ 1024 = 12%。现在被拒绝的几率是(65535 - 64944) / 65535 = 1%。我们不太可能拒绝随机生成的数字。

代码语言:javascript
复制
running <- true
while running
  num <- two byte random
  if (num < 64944)
    result <- num MOD 902
    running <- false
  endif
endwhile
return result + 55
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33609404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档