如何从哈希中获取数字

How to get a number from a hash

本文关键字:获取 数字 哈希中      更新时间:2023-09-26

我正试图在node.js中的01000000之间创建随机数(100万)。哈希为:

var hash = crypto.createHmac('sha512', "value").update("another value").digest('hex');
//d89c8a02a8b4e2461eeddcc3d8e85f2dfdab62968a329840ec5df2c0be2852eb9321cb35ff8fd5f43e97857a618d35edf9ba7fff56319c56eae4f8509f02e7eb

随机数

var number = parseInt(hash.substring(0, 5), 16); // 887240

但有时我得到的数字超过100万,我该如何防止这种情况发生?

SimpleDRBG定义了一个简单(不符合FIPS)的DRBG,它基本上只是NIST HMAC_Generate函数,它使用HMAC值链。请注意,请求1个字节,然后再请求另一个字节与同时请求2个字节不同。


RandomInt类是可以使用该类的randomBytes或Node.js的crypto模块的类。它创建任何随机有界数或范围内的数。

boundedRandomNumber函数首先计算需要多少字节,这比所需的字节数高一点。然后,这些字节被转换为一个大整数,称为candidate。然后返回该值,模为界。

while循环确保没有向频谱的低端倾斜,因为最高CCD_;在执行模量CCD_ 9之后结合。在这种情况下,会请求更多的字节。然而,在当前的实现中,循环被多次执行的几率不是很高,因此这些函数应该相对高效。


因此文件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;
}

CCD_ 11应包含:

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);

只要你想使用哈希来解决你的问题,你就可以:根据维基百科"……随机性提取器,如加密哈希函数,可以用来从非均匀随机源中获得比特的均匀分布,尽管比特率较低。"

从良好的加密哈希函数输出中取第一个连续的五个十六进制数字[Log2(10^6)+1](SHA512是您的选择)。测试它是否小于或等于你的上限。否则测试接下来的5个十六进制数字。输出也将具有均匀分布。20位随机数大于上限的概率为p=48575/1048576=0.0463247如果你在25个不重叠的子集上分割128个数字,那么所有子集坏的概率是p^25=4.41*10^-34。如果这是不可忽略的,那么计算下一个散列。我选择了不重叠的子集来进行最简单的概率计算(对于子集独立性),但对于您的任务,您可以按1个十六进制数字移动并测试多达124个子集。