I see three alternatives.
We published an Open Source AES-256 based Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). It has a proven entropy generator, and you can have several generators (e.g. one per thread). It uses AES-NI hardware acceleration, so is very fast.
Or, if you want to generate unique IDs, you can use code similar to this, for generating one 32-bit random value at a time:
{$ifdef CPUINTEL}
/// get 32-bit value from NIST SP 800-90A compliant RDRAND Intel x86/x64 opcode
function RdRand32: cardinal;
{$ifdef CPU64}
{$ifdef FPC}nostackframe; assembler;
asm
{$else}
asm
.noframe
{$endif FPC}
{$endif CPU64}
{$ifdef CPU32}
asm
{$endif}
// rdrand eax: same opcodes for x86 and x64
db $0f,$c7,$f0
// returns in eax, ignore carry flag (eax=0 won't hurt)
end;
// https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
{$endif}
var
rs1: cardinal = 2654435761;
rs2: cardinal = 668265263;
rs3: cardinal = 3266489917;
function Random32: cardinal;
begin
{$ifdef CPUINTEL}
if cfRAND in CpuFeatures then begin
result := RdRand32;
exit;
end;
{$endif}
result := rs1;
rs1 := ((result and -2)shl 12) xor (((result shl 13)xor result)shr 19);
result := rs2;
rs2 := ((result and -8)shl 4) xor (((result shl 2)xor result)shr 25);
result := rs3;
rs3 := ((result and -16)shl 17) xor (((result shl 3)xor result)shr 11);
result := rs1 xor rs2 xor result;
end;
It will use HW-based PRNG available on latest Intel CPUs, or fast a gsl_rng_taus2 generator by P. L'Ecuyer (with a period=2^88, i.e. about 10^26), which is a much better pattern than the one in Random()
. For multi-thread, use threadvar instead of var for rs1, rs2 and rs3. And do not forget to XOR the initial values, e.g. with some minimal entropy, at least QueryPerformanceCounter().
Last but not least, if you want some unique values, not perfectly random, you may use simply:
var g: TGUID;
...
CreateGUID(g);
Here the generated TGUID is known to be unique, by the OS. You can easily use the 128-bit of the TGUID
content, which could be used as keys in a better way than 332-bit, even over the Internet. A lot of systems just rely on this API call, if what you need is unicity, not randomness. You may use either the string representation, or the 128-bit = 432-bit binary content.