jsrsasign icon indicating copy to clipboard operation
jsrsasign copied to clipboard

getBigRandom() is incorrect

Open FGasper opened this issue 8 years ago • 9 comments

    this.getBigRandom = function (limit) {
	return new BigInteger(limit.bitLength(), rng)
	.mod(limit.subtract(BigInteger.ONE))
	.add(BigInteger.ONE)
	;
};

The above will unfairly privilege low numbers at the expense of high numbers. The initial BigInteger object is equally likely to be any number with the same bit length as “limit”. The modulo operation, then, makes for at least two separate ways by which the result of the operation can be a low number, while leaving only one path for the highest.

Example:

var r_int = Math.floor( 10 * Math.random() );
var r_int2 = r_int % 8;

r_int is equally likely to be any of the integers 0 to 9, inclusive; i.e., each integer has a 0.1 probability.

r_int2, however, has a .2 probability of being 0 and a .2 probability of being 1, while the probability of other possible r_int2 values is still 0.1.

FGasper avatar Dec 10 '16 15:12 FGasper

@FGasper Mayby I just don't understand your example, but with those two lines you will always get a number less than 10, right? So why do you write about getting greater than 10?

Ruffio avatar Jun 29 '17 20:06 Ruffio

@Ruffio Sorry, that was a bad example before. I’ve updated it to be (hopefully) clearer.

FGasper avatar Jul 05 '17 15:07 FGasper

@FGasper do you have an idea of a 'correct' implementation of 'getBigRandom'? This is a little over my head... :-(

Ruffio avatar Jul 05 '17 15:07 Ruffio

What is getBigRandom’s exact purpose? It seems to exclude 0 as a return value; is that by design?

A more-correct implementation would be to discard any random values that are greater than the maximum value we’d want to return.

Maybe something like:

    this.getBigRandom = function (limit) {
        var limit_minus_1 = limit.subtract(BigInteger.ONE);
	while (1) {
            var int = new BigInteger(limit.bitLength(), rng);
            if (int.lessThan( limit_minus_1 )) {   // not sure if this exists
                return int.add(BigInteger.ONE);
            }
	}
};

Sorry for the untested-ness … hopefully later I can flesh it out a bit more.

FGasper avatar Jul 05 '17 15:07 FGasper

@kjur is this bias of probability by intend or accidental? Should it be changed?

Ruffio avatar Jul 25 '17 07:07 Ruffio

@kjur is this bias of probability by intend or accidental? Should it be changed?

Ruffio avatar Jul 29 '17 19:07 Ruffio

@kjur is this bias of probability by intend or accidental? Should it be changed?

Ruffio avatar Aug 16 '17 15:08 Ruffio

@kjur is this bias of probability by intend or accidental? Should it be changed?

Ruffio avatar Aug 27 '17 05:08 Ruffio

@kjur what do you think?

JerryUS2019 avatar Mar 06 '19 13:03 JerryUS2019