javascript - 如何从哈希中获取数字

标签 javascript node.js random cryptography

我正在尝试在 node.js 中创建 01000000(一百万)之间的随机数。哈希是:

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,它基本上只是使用 HMAC 值链的 NIST HMAC_Generate 函数。请注意,请求 1 个字节,然后再请求另一个字节与同时请求 2 个字节不同。


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

boundedRandomNumber 函数首先计算要求的字节数,比要求的字节数高一点。然后将这些字节转换为一个大整数,称为 candidate。然后返回这个值,对边界取模。

while 循环确保不会偏向频谱的低端,因为最高的 candidate 值可能会返回 0 和 X 之间的值,其中 X < bound after performing modules 绑定(bind)。在这种情况下,需要更多字节。在当前的实现中,循环被多次执行的可能性不是很高,因此这些函数应该是相对高效的。


所以文件 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);

关于javascript - 如何从哈希中获取数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26443450/

相关文章:

javascript 对象嵌套回调

python - Django 获取随机对象

java - 我应该选择 i > 1 还是 i >= 1 进行随机洗牌

javascript - 使用 JavaScript 选择下拉选项

javascript - 使用 css 剪辑路径在多边形形状上进行 jQuery 拖放

c# - 在 C# 中使用匿名类型创建对象文字的问题

javascript - JS ES6 Promise 被无缘无故地调用

node.js - 蒙戈错误: write EPIPE in node server

javascript - 在输入参数无效的情况下对 Promise 进行单元测试

algorithm - 二元向量的条件采样(?)