Actually you appear to be right.

From system unit:

function random(l:longint): longint;

begin

{ otherwise we can return values = l (JM) }

if (l < 0) then

inc(l);

random := longint((int64(cardinal(genrand_MT19937))*l) shr 32);

end;

function random(l:int64): int64;

begin

{ always call random, so the random generator cycles (TP-compatible) (JM) }

random := int64((qword(cardinal(genrand_MT19937)) or ((qword(cardinal(genrand_MT19937)) shl 32))) and $7fffffffffffffff);

if (l<>0) then

random := random mod l

else

random := 0;

end;

genrand_MT19937 returns a random 32 bit value. Lets assume that part to be as correct as can be.

There is a generic problem.

If you do "Random(100)" you need to map the 2^32 values to 0..99. But 2^31 is not int dividable by 100. So some of 0..99 will be more likely.

Once you evenly distributed 4,294,967,200 out of the 4,294,967,296 values, you have 96 values left, to evenly distribute.

How to you map 96 values to 0..99 so that each of 0..99 is equally likely chosen?

This problem then manifests in both of the implementations

64bit:

random := random mod l

means that 96 to 99 are slightly less likely.

(If it was QWord) With random (2^63 + n), the last 2*n values are only half as likely to occur.

32bit:

The numbers with different likelihood are equally spread across the requested range.

--

The issue is that any stable function to map the result of genrand_MT19937 to a given range will have the same problem.

You would need additional inputs to map them different (e.g counting how often "random" was called.)

But such additional input may be guess-able. And if it is part of the random result, then an attacker may be able to make predictions based on that.

Of course if an attacker knows your range, and that you use the fpc implementation, said attacker can make guesses too.

--

Since using "Mod" the bias on the numbers depends on how big the range is (relative to the max of genrand_MT19937 ), you can get a bigger random number, by calling genrand_MT19937 several times.

It still will be biased, but statistically less likely.