我试图在0
中的1000000
和node.js
(1百万)之间创建随机数。哈希是:
var hash = crypto.createHmac('sha512', "value").update("another value").digest('hex');
//d89c8a02a8b4e2461eeddcc3d8e85f2dfdab62968a329840ec5df2c0be2852eb9321cb35ff8fd5f43e97857a618d35edf9ba7fff56319c56eae4f8509f02e7eb
随机数
var number = parseInt(hash.substring(0, 5), 16); // 887240
但有时我的数字超过100万,我该如何防止这种情况?
答案 0 :(得分:1)
SimpleDRBG定义了一个简单的(非FIPS兼容的)DRBG,它基本上只是NIST HMAC_Generate函数,它使用一系列HMAC值。请注意,请求1个字节,后跟另一个字节与同时询问2个字节不同。
RandomInt类是可以使用该类的randomBytes
或Node.js的crypto
模块的类。它会创建任意随机数字或范围内的数字。
boundedRandomNumber
函数首先计算要求的字节数,这比所需的字节数要高一些。然后将这些字节转换为一个大整数,称为candidate
。然后返回此值,模拟边界。
while循环确保不存在朝向频谱的低端的偏斜,因为最高candidate
值可以返回0到X之间的值,其中X <0。在执行模数bound
后绑定。在这种情况下,请求更多字节。对于当前的实现,循环被多次使用的可能性不是很高,所以这些函数应该相对有效。
因此文件simpledrbg.js
应包含:
crypto = require('crypto');
exports.SimpleDRBG = function (k) {
this.k = k;
this.v = new Buffer(0);
}
exports.SimpleDRBG.prototype.randomBytes = function(bytes) {
var result = new Buffer(0);
var generatedBytes = 0;
while (generatedBytes < bytes) {
this.hmac = crypto.createHmac('sha512', this.k);
this.hmac.update(this.v);
this.v = this.hmac.digest();
var tocopy = Math.min(this.v.length, bytes - generatedBytes);
if (tocopy == this.v.length) {
result = Buffer.concat([result, this.v]);
} else {
var vslice = this.v.slice(0, tocopy);
result = Buffer.concat([result, vslice]);
}
generatedBytes += tocopy;
}
return result;
}
和randomint.js
应包含:
crypto = require('crypto'),
bigint = require('bigint');
drbg = require('./simpledrbg');
function RandomInt(randomizer) {
this.randomizer = randomizer;
}
/**
* Returns a bounded random number, i.e. in the range [0..bound).
* The highest possible value that may be returned is bound - 1.
* Use boundedRandomNumber (bound + 1) if you want the bound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.boundedRandomNumber = function (bound) {
BYTE_SIZE = 8;
bigBound = bigint(bound);
bigBoundLen = bigint(bigBound.bitLength());
// request a higher number of bytes just to be sure that
// the candidates are selected with high probability
bytesToRequest = bigBoundLen.add(BYTE_SIZE).sub(1).div(BYTE_SIZE).add(1);
// bigBound won't fit an integral number of times in the max value returned
// so if it is higher than the largest n times bigBound, we need to try
// again
maxCandidateExcl = bigint(0x100).pow(bytesToRequest).div(bigBound).mul(bigBound);
// just an assignment that will skip the initial test
candidate = maxCandidateExcl;
while (candidate.ge(maxCandidateExcl)) {
bytes = this.randomizer.randomBytes(bytesToRequest.toNumber());
candidate = bigint.fromBuffer(bytes);
}
// return the well distributed candidate % bound
return candidate.mod(bigBound).toNumber();
}
/**
* Returns a ranged random number, i.e. in the range [lowerBound..upperBound).
* The highest possible value that may be returned is upperBound - 1.
* Use rangedRandomNumber (lowerBound, upperBound + 1) if you want the upperBound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.rangedRandomNumber = function (lowerBound, upperBound) {
return lowerBound + boundedRandomNumber (upperBound - lowerBound);
}
var randomIntTRNG = new RandomInt(crypto);
var testTRNG = randomIntTRNG.boundedRandomNumber(1000000);
console.log(testTRNG);
var randomIntDRNG = new RandomInt(new drbg.SimpleDRBG('seed'));
var testDRNG = randomIntDRNG.boundedRandomNumber(1000000);
console.log(testDRNG);
答案 1 :(得分:1)
只要您希望对问题使用哈希,您就可以:根据维基百科“......随机提取器,例如加密哈希函数,可以用来接近来自非均匀随机的比特的均匀分布来源,虽然比特率较低。“
从好的加密哈希函数输出中取出第一个连续的五个十六进制数字[Log2(10 ^ 6)+ 1](SHA512是您的选择)。测试它是否小于或等于你的上限。 否则测试下5个十六进制数字。输出也将具有均匀分布。 20位随机数将大于上限的概率为p = 48575/1048576 = 0.0463247 如果在25个非重叠子集上拆分128位数,则所有子集都不好的概率为p ^ 25 = 4.41 * 10 ^ -34。如果这不可忽略,那么计算下一个哈希值。我采用非重叠子集进行最简单的概率计算(对于子集独立性),但对于您的任务,您可以移动1个十六进制数字并测试最多124个子集。