A strong PRNG

General FreeBASIC programming questions.
Post Reply
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

@dafhi
Thanks for the info. I mostly use Linux for programming. I tested my code on Windows 10 it took about 6 hours.
I ported my code to C language it takes under 4 hours now. I found using the Linux command line pipe is much faster than FreeBasic running on Windows. To pipe using on the command line on Linux I use "./prng | ./RND_test stdin32" very simple to use. There were no anomalies just a few warnings "Evaluation unusual".
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

In FreeBasic V 1.09, the pipe function does not work with Linux. So I wrote a small C program for PractRand using Linux.
I discovered that Windows has a Command Line Pipe function as well. I was just going to test it on Windows 10, and during an update it crashed and wouldn't boot. Maybe someone could test it with Windows if they have the GCC compiler installed on Windows. My prng program no longer failed the RNG_test after I changed my code to send out one byte at a time to the pipe. It still puts out more than 4 GB a minute. Here's a link for the GCC compiler for Windows. https://winlibs.com/#download-release
I know there is nothing special about the algorithm; there are many out there for testing.

Code: Select all

/* I am not sure how to compile C language programs using Windows possibly the same as Linux */
/* To Compile on Windows using the GCC compiler possibly "gcc -Wall prng.c -o prng"  */
/* The Windows command line Pipe should be "prng | RNG_test stdin8"  */

/* to compile on the command line using Linux is  "gcc -Wall prng.c -o prng" */
/* The command line pipe for Linux is "./prng | ./RNG_test stdin8" */
/* Use CTRL+C to end program */
/* prng and RNG_test have to be in the same directory */

/* prng.c */
#include <stdio.h>
int main() { 
unsigned long r1,r2;
unsigned char rn;
r1 = 521288629; r2 = 3624316069; /* 2 starting values */
while(1) {
   r1 = r1 * (r1 ^ 65535) + (r1 >> 16);
   r2 = r1 * (r2 ^ 65535) + (r2 >> 16);
   r1 = (r1 << 16) + r2;
   rn = (r1 % 256);
   printf("%c",rn);
   /* printf("%d\n",rn); */
}
return 0;
}
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

"Evaluation unusual" is the lowest level of anomaly reported. Random numbers, by their very nature, have anomalies, even quantum random numbers. 'Evaluation unusual" can be ignored.

The level reported depends upon the value of 'p' – the lower the value, the greater the anomaly. It is a carry over from George Marsaglia who introduced the concept.

Marsaglia wrote:

Thus, you should not be surprised with occasional p-values near 0 or 1, such as .0012 or .9983. When a bit stream really FAILS BIG, you will get p's of 0 or 1 to six or more places. By all means, do not, as a Statistician might, think that a p < .025 or p> .975 means that the RNG has "failed the test at the .05 level". Such p's happen among the hundreds that DIEHARD produces, even with good RNG's. So keep in mind that " p happens".
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

This has only been tested on Linux and is very slow.
Command Line Pipe Test for FreeBasic.

Code: Select all

'' FreeBasic Version of the Command Line Pipe Test
'' This runs way to slow on Linux The C version is so much faster
'' Command Line Pipe Test using Linux ./prng | ./RNG_test stdin8
'' Command line pipe for Windows should be prng | RNG_test stdin8

'' r1 and r2 were Ulong The C version is unsigned long
'' I had to change r1 and r2 as Uinteger or it failed immediately
Dim As Uinteger r1,r2
Dim As Ubyte rb
r1 = 521288629:r2 = 3624316069 ' Two starting values

Do
   r1 = r1 * (r1 xor 65535) + (r1 shr 16)
   r2 = r2 * (r2 xor 65535) + (r2 shr 16)
   r1 = (r1 shl 16) + r2
   rb = (r1 mod 256)
   print chr(rb);
'' print rb
loop
Last edited by neil on Mar 29, 2023 5:59, edited 1 time in total.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

Throwing one byte at a time to PractRand will be slow. I throw a 1MiB string at it.

This is what I recently used to test CryptoRndIV.

My_Prng.bas

Code: Select all

#include "I:\FreeBASIC\CryptoRnd\CryptoRndIV.bas"
Dim Shared S As String * 1048576
Dim As ULong Ptr SPtr, BasePtr
Dim As Long j

SPtr = Cptr( Ulong Ptr, VarPtr(S) )
BasePtr = SPtr

Do
  For j = 1 to 262144
    *SPtr = CryptoDW
    SPtr += 1
  Next
  Print S;
  SPtr = BasePtr
Loop
Regarding PractRand's command line, I use this:

My_Prng.exe | rng_test stdin32 -multithreaded. If the generator outputs 64-bit, then use stdin64.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: A strong PRNG

Post by dodicat »

This practrand thing.
C is probably the most powerful high level language around.
It has been used for decades, we can assume that msvcrt.dll is a really well optimised and tested windows dll, it is used everywhere.
Then why should the C rand() function be anything but pretty good?
Would it still be in use if it was useless?
According to practrand it is useless:

Code: Select all

RNG_test using PractRand version 0.94
RNG = RNG_stdin32, seed = unknown
test set = core, folding = standard (32 bit)

rng=RNG_stdin32, seed=unknown
length= 256 megabytes (2^28 bytes), time= 2.7 seconds
  Test Name                         Raw       Processed     Evaluation
  BCFN(2+0,13-2,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+1,13-2,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+2,13-3,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+3,13-3,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+4,13-3,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+5,13-4,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+6,13-5,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+7,13-5,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+8,13-6,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+9,13-6,T)                  R>+99999  p = 0           FAIL !!!!!!!!
  BCFN(2+10,13-7,T)                 R=+69095  p = 0           FAIL !!!!!!!!
  BCFN(2+11,13-8,T)                 R=+40957  p = 0           FAIL !!!!!!!!
  BCFN(2+12,13-8,T)                 R=+20441  p =  1e-5188    FAIL !!!!!!!!
  BCFN(2+13,13-9,T)                 R=+11734  p =  8e-2638    FAIL !!!!!!!!
  BCFN(2+14,13-9,T)                 R= +5853  p =  3e-1316    FAIL !!!!!!!!
  DC6-9x1Bytes-1                    R>+99999  p = 0           FAIL !!!!!!!!
  Gap-16:A                          R>+99999  p = 0           FAIL !!!!!!!!
  Gap-16:B                          R>+99999  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(1,14-0)              R>+99999  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(2,14-0)              R>+99999  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(3,14-0)              R>+99999  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(4,14-1)              R=+96289  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(5,14-2)              R=+68092  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(6,14-2)              R=+45371  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(7,14-3)              R=+32087  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(8,14-4)              R=+22694  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(9,14-5)              R=+16055  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:(10,14-5)             R= +9984  p =  6e-8277    FAIL !!!!!!!!
  FPF-14+6/16:(11,14-6)             R= +7141  p =  3e-5465    FAIL !!!!!!!!
  FPF-14+6/16:(12,14-7)             R= +5079  p =  3e-4042    FAIL !!!!!!!!
  FPF-14+6/16:(13,14-8)             R= +3583  p =  2e-2578    FAIL !!!!!!!!
  FPF-14+6/16:(14,14-8)             R= +2116  p =  6e-1523    FAIL !!!!!!!!
  FPF-14+6/16:all                   R>+99999  p = 0           FAIL !!!!!!!!
  FPF-14+6/16:cross                 R>+99999  p = 0           FAIL !!!!!!!!
  BRank(12):128(4)                  R= +2717  p~=  1e-1445    FAIL !!!!!!!!
  BRank(12):256(4)                  R= +5644  p~=  9e-3003    FAIL !!!!!!!!
  BRank(12):384(1)                  R= +4286  p~=  3e-1291    FAIL !!!!!!!!
  BRank(12):512(2)                  R= +8132  p~=  7e-2449    FAIL !!!!!!!!
  BRank(12):768(1)                  R= +8678  p~=  3e-2613    FAIL !!!!!!!!
  BRank(12):1K(2)                   R=+16412  p~=  1e-4941    FAIL !!!!!!!!
  BRank(12):1536(1)                 R=+17461  p~=  3e-5257    FAIL !!!!!!!!
  BRank(12):2K(1)                   R=+23316  p~=  7e-7020    FAIL !!!!!!!!
  mod3n(5):(0,9-1)                  R>+99999  p = 0           FAIL !!!!!!!!
  mod3n(5):(1,9-1)                  R>+99999  p = 0           FAIL !!!!!!!!
  TMFn(2+0):wl                      R=+56712  p~=  0          FAIL !!!!!!!!
  TMFn(2+1):wl                      R=+28231  p~=  0          FAIL !!!!!!!!
  TMFn(2+2):wl                      R=+14039  p~=  0          FAIL !!!!!!!!
  TMFn(2+3):wl                      R= +7178  p~=  0          FAIL !!!!!!!!
  [Low8/32]BCFN(2+0,13-3,T)         R=+105.9  p =  6.6e-50    FAIL !!!!
  [Low8/32]BCFN(2+1,13-3,T)         R=+119.9  p =  1.4e-56    FAIL !!!!
  [Low8/32]BCFN(2+2,13-4,T)         R= +75.3  p =  7.3e-33    FAIL !!!
  [Low8/32]BCFN(2+3,13-4,T)         R= +85.2  p =  3.5e-37    FAIL !!!
  [Low8/32]BCFN(2+4,13-5,T)         R= +62.6  p =  1.1e-24    FAIL !!
  [Low8/32]BCFN(2+5,13-5,T)         R= +68.8  p =  4.0e-27    FAIL !!
  [Low8/32]BCFN(2+6,13-6,T)         R= +80.8  p =  4.0e-28    FAIL !!
  [Low8/32]BCFN(2+7,13-6,T)         R= +34.3  p =  3.6e-12   VERY SUSPICIOUS
  [Low8/32]BCFN(2+8,13-7,T)         R= +29.9  p =  1.2e-9   very suspicious
  [Low8/32]BCFN(2+9,13-8,T)         R= +33.0  p =  2.5e-9   very suspicious
  [Low8/32]BCFN(2+10,13-8,T)        R= +41.6  p =  1.6e-11   VERY SUSPICIOUS
  [Low8/32]BCFN(2+11,13-9,T)        R= +64.3  p =  1.4e-15    FAIL
  [Low8/32]BCFN(2+12,13-9,T)        R= +42.0  p =  1.4e-10  very suspicious
  [Low8/32]DC6-9x1Bytes-1           R= +1019  p =  2.5e-649   FAIL !!!!!!!
  [Low8/32]Gap-16:A                 R=+18748  p = 0           FAIL !!!!!!!!
  [Low8/32]Gap-16:B                 R= +6757  p =  5e-6018    FAIL !!!!!!!!
  [Low8/32]FPF-14+6/16:(0,14-0)     R= -43.6  p =1-8.4e-40    FAIL !!!
  [Low8/32]FPF-14+6/16:(1,14-0)     R= +38.0  p =  9.0e-35    FAIL !!!
  [Low8/32]FPF-14+6/16:(2,14-1)     R= +26.9  p =  1.4e-23    FAIL !!
  [Low8/32]FPF-14+6/16:(3,14-2)     R= +19.0  p =  2.1e-16    FAIL
  [Low8/32]FPF-14+6/16:(4,14-2)     R=+651.5  p =  1.4e-569   FAIL !!!!!!!
  [Low8/32]FPF-14+6/16:(5,14-3)     R=+460.7  p =  1.3e-403   FAIL !!!!!!!
  [Low8/32]FPF-14+6/16:(6,14-4)     R=+325.9  p =  3.2e-266   FAIL !!!!!!
  [Low8/32]FPF-14+6/16:(7,14-5)     R=+230.6  p =  5.1e-191   FAIL !!!!!!
  [Low8/32]FPF-14+6/16:(8,14-5)     R=+107.0  p =  1.3e-88    FAIL !!!!
  [Low8/32]FPF-14+6/16:(9,14-6)     R= +76.6  p =  1.1e-58    FAIL !!!!
  [Low8/32]FPF-14+6/16:(10,14-7)    R= +54.4  p =  3.8e-43    FAIL !!!
  [Low8/32]FPF-14+6/16:(11,14-8)    R= +37.6  p =  4.3e-27    FAIL !!
  [Low8/32]FPF-14+6/16:(12,14-8)    R= +18.1  p =  4.7e-13   VERY SUSPICIOUS
  [Low8/32]FPF-14+6/16:(13,14-9)    R= +11.5  p =  1.4e-7   mildly suspicious
  [Low8/32]FPF-14+6/16:(16,14-11)   R= +57.9  p =  4.4e-26    FAIL !!
  [Low8/32]FPF-14+6/16:all          R=+371.3  p =  5.4e-348   FAIL !!!!!!!
  [Low8/32]mod3n(5):(0,9-2)         R= +22.4  p =  2.4e-12    FAIL
  [Low8/32]mod3n(5):(1,9-2)         R= +28.8  p =  8.2e-16    FAIL !
  [Low8/32]mod3n(5):(2,9-3)         R= +18.2  p =  1.3e-9    VERY SUSPICIOUS
  [Low8/32]mod3n(5):(3,9-3)         R= +19.1  p =  4.7e-10   VERY SUSPICIOUS
  [Low8/32]TMFn(2+0):wl             R= +5339  p~=  0          FAIL !!!!!!!!
  [Low8/32]TMFn(2+1):wl             R= +3893  p~=  0          FAIL !!!!!!!!
  [Low1/32]BCFN(2+0,13-5,T)         R= +7248  p =  1e-2837    FAIL !!!!!!!!
  [Low1/32]BCFN(2+1,13-5,T)         R= +6667  p =  3e-2610    FAIL !!!!!!!!
  [Low1/32]BCFN(2+2,13-6,T)         R= +4055  p =  2e-1389    FAIL !!!!!!!!
  [Low1/32]BCFN(2+3,13-6,T)         R= +6416  p =  8e-2198    FAIL !!!!!!!!
  [Low1/32]BCFN(2+4,13-6,T)         R= +5315  p =  1e-1820    FAIL !!!!!!!!
  [Low1/32]BCFN(2+5,13-7,T)         R= +3846  p =  1e-1157    FAIL !!!!!!!!
  [Low1/32]BCFN(2+6,13-8,T)         R= +1505  p =  5.3e-383   FAIL !!!!!!!
  [Low1/32]BCFN(2+7,13-8,T)         R= +3949  p =  4e-1003    FAIL !!!!!!!!
  [Low1/32]BCFN(2+8,13-9,T)         R=+729.1  p =  5.8e-165   FAIL !!!!!
  [Low1/32]BCFN(2+9,13-9,T)         R= +1458  p =  9.3e-329   FAIL !!!!!!
  [Low1/32]DC6-9x1Bytes-1           R=+68037  p = 0           FAIL !!!!!!!!
  [Low1/32]Gap-16:A                 R>+99999  p = 0           FAIL !!!!!!!!
  [Low1/32]Gap-16:B                 R>+99999  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(0,14-2)     R=+37691  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(1,14-2)     R=+31677  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(2,14-3)     R=+22358  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(3,14-4)     R=+15499  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(4,14-5)     R=+11695  p =  2e-9695    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(5,14-5)     R= +9101  p =  3e-7545    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(6,14-6)     R= +6763  p =  8e-5176    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(7,14-7)     R= +4235  p =  2e-3370    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(8,14-8)     R= +2737  p =  1e-1969    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(9,14-8)     R= +2762  p =  6e-1988    FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:(10,14-9)    R= +1300  p =  3.8e-819   FAIL !!!!!!!
  [Low1/32]FPF-14+6/16:(11,14-10)   R=+729.2  p =  1.6e-388   FAIL !!!!!!!
  [Low1/32]FPF-14+6/16:all          R=+58502  p = 0           FAIL !!!!!!!!
  [Low1/32]FPF-14+6/16:cross        R=+891.3  p =  8.4e-723   FAIL !!!!!!!
  [Low1/32]BRank(12):512(1)         R= +8139  p~=  3e-2451    FAIL !!!!!!!!
  [Low1/32]mod3n(5):(0,9-3)         R=+426.6  p =  9.3e-222   FAIL !!!!!!
  [Low1/32]mod3n(5):(1,9-4)         R=+246.6  p =  1.7e-112   FAIL !!!!!
  [Low1/32]mod3n(5):(2,9-4)         R=+291.2  p =  9.0e-133   FAIL !!!!!
  [Low1/32]mod3n(5):(3,9-5)         R=+146.6  p =  4.3e-63    FAIL !!!!
  [Low1/32]mod3n(5):(4,9-5)         R=+138.6  p =  1.1e-59    FAIL !!!!
  [Low1/32]mod3n(5):(5,9-6)         R= +98.8  p =  1.4e-34    FAIL !!!
  [Low1/32]mod3n(5):(6,9-6)         R= +48.7  p =  1.8e-17    FAIL !
  [Low1/32]mod3n(5):(7,9-6)         R= +51.5  p =  2.0e-18    FAIL !
  [Low1/32]mod3n(5):(8,9-6)         R=+150.6  p =  2.7e-52    FAIL !!!!
  [Low1/32]mod3n(5):(9,9-6)         R=+134.1  p =  1.2e-46    FAIL !!!
  ...and 38 test result(s) without anomalies

 
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

Failing at 256 GiB gives at least 32 Gigs of usable 32-bit granularity in [0,1) so it is not exactly useless.

PowerBASIC's RND fails PractRand in the low KiBs. Now that is useless.

Mersenne Twister was OK up to PractRand v0.93 but fails v0.94 at 256 GiB – the same as C rand().

However, there are so many PRNGs nowadays which pass PractRand beyond one TiB, have a good distribution uniformity, and are fairly fast then why bother with old stuff like C rand() and Mersenne Twister.
hhr
Posts: 208
Joined: Nov 29, 2019 10:41

Re: A strong PRNG

Post by hhr »

I made a mistake. For the test up to 1TB in my post, I modified and used the routine from deltarho[1859]:
viewtopic.php?p=283574#p283574
The routine from deltarho[1859] is 2.5 times faster than my routine. That's the only way my computer managed 1 terabyte in 5.5 hours.

Code: Select all

RNG_test using PractRand version 0.94
RNG = RNG_stdin32, seed = unknown
test set = core, folding = standard (32 bit)

rng=RNG_stdin32, seed=unknown
length= 1 terabyte (2^40 bytes), time= 19704 seconds
  no anomalies in 303 test result(s)
I also replaced (r1 and 65535) and (r2 and 65535) with loword(r1) in prng. This resulted in a small advantage in computing time. Moreover, prng then already fails at 64KB, which was my wish. All generators should have a low quality.

Linking generators only makes sense if the generators produce independent sequences. Only then does the entropy increase. That is like mixing texts that are independent of each other. Because you can put everything into one function, you can also use it to construct your own generators.

Instead of 'xor' I used '+' because the carry-over of the addition influences the result favourably.

Note
#cmdline "-gen gcc -O 2"
in dodicat's post. As the first line, this can give a speed advantage.

Translated with www.DeepL.com/Translator (free version)

deltarho[1859]'s routine (modified):

Code: Select all

chdir "Path to PractRand's RNG_test.exe" ' PractRand Version 0.94
dim as string cs = "RNG_test stdin32"
cs &= " -tlmin 1TB"
'cs &= " -tlmaxonly"
cs &= " -multithreaded"
open pipe cs for binary access write as #1

dim shared S as string * 2097152
dim as ulong ptr SPtr, BasePtr
dim as long j

SPtr = cptr(ulong ptr, strptr( S ))
BasePtr = SPtr

do
   for j = 1 to 524288 ' =2097152/4 (Ulong has four byte)
      *SPtr = nextnumber32
      SPtr += 1
   next
   put #1,,S
   SPtr = BasePtr
loop ' To be ended with ^c
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

deltarho[1859]
On Linux cat /dev/urandom | ./RNG_test stdin64 -multithreaded outputs characters to stdout like this "mSyN@hX^" 8 characters = 8 Bytes or 64 Bits. Say my program outputs numbers 255 128 64 88 233 191 25 99 = 8 bytes or 64 bits Those 8 numbers = 20 characters 8 x 20 = 160 bits. Does PractRand read number 255 as a number or 3 characters or 3 Bytes? On my test program I am sending my numbers out as single characters. If Practrand is reading 3 digit numbers or 2 digit numbers as characters that would add up to to more than 64bits. On Linux /dev/random passed PractRand to 2 TeraBytes in about 2 hours and 21 minutes Approximately how long should it take you for a 2 TeraByte test? On my C program it takes over over 2 hours for a 1 TeraByte test using "stdin32 -multithreaded" almost doubled the speed. I think I might be overloading Practrand by not fully understanding how it works. I would like to get past the one byte barrier output.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

@neil

If your generator outputs 32 bits, then use stdin32. If your generator outputs 64 bits, then use stdin64. It is as simple as that.
Approximately how long should it take you for a 2 TeraByte test?
Two variables determine the answer to that: One the generator being tested and two the speed of your CPU.

Best procedure: Kill as many running programs you can, Run PractRand just before you go to bed. :)
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

deltarho[1859]
Even though my C program only outputs 8 bits at a time.The RNG_test "stdin32 -multithreaded" option still worked. This almost double the speed of a TeraByte test from around 4 hours to around 2 plus hours. I thought I had to use "stdin8" since my program is only generating an 8 bit output.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

PractRand will do whatever we tell it.

Given true random numbers, which only exist in the quantum world, 4×8 random bits is the same as 32 random bits. That is not true for PRNGs. In practice, I doubt that not using the actual output size will make much difference to the analysis. If we do not know the output size, the author of PractRand suggests we use stdin8. If we use stdin64 when the output is 32-bit then 32-bit tests will not be carried out. Yes, the analysis will be quicker, but it will not be a proper analysis of a 32-bit output.

Fourmilab's ENT application is not interested in output size: It will do either a byte analysis or a bit analysis. Keep in mind that all ENT's metrics are concerned with distribution uniformity, except the last one.
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

This passed Practrand to Gigabyte with Linux.
Practrand 8 Byte. test This program joins 8 characters as an 8 Byte 64 bit PRNG string for testing Practrand. The results were sending 1 Byte to Practrand took 383 seconds. Sending an 8 byte string to Practrand took 125 seconds. This was only for 1 GB. This is still to slow the C languge version puts out over 4 GB a minute at only I byte out at a time. Also I know this is poor coding. This should of been put in a For loop to an array but this was only for testing. An 8 Byte string is 258 seconds faster For a 1 Gigabyte test.

Code: Select all

'' Another PRNG TEST by Neil
'' To test ./prng | ./RNG_test stdin64 -multithreaded
'' This passed Practrand to Gigabyte with Linux.

dim as uinteger i,r1,r2
dim as ushort sr
r1 = 521288629:r2 = 3624316069
Dim as string sa,s1,s2,s3,s4,s5,s6,s7,s8
Do
    sa ="":s1="":s2 ="":s3 ="":s4 =""
    s5 ="":s6 ="":s7 ="":s8 = ""
   
    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s1 = chr(sr)

    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s2 = chr(sr)

    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s3 = chr(sr)
 
    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s4 = chr(sr)
 
    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s5 = chr(sr)

    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s6 = chr(sr)

    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s7 = chr(sr)
 
    r1 = r1 * (r1 xor r2) + (r1 shr 16)
    r2 = r2 * (r2 xor r1) + (r2 shr 16)
    r1 = (r1 shl 16) + r2  
    sr = (r1 mod 256)
    s8 = chr(sr)

   sa = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8
   print sa;
Loop
Last edited by neil on Mar 29, 2023 5:57, edited 1 time in total.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A strong PRNG

Post by deltarho[1859] »

@neil

With mod 256 you are throwing three quarters of your hard-earned ulongs out of the window.

Feed PractRand your generator's ulongs and request from PractRand a byte analysis with stdin8.
neil
Posts: 591
Joined: Mar 17, 2022 23:26

Re: A strong PRNG

Post by neil »

@deltarho[1859]
The algorithm only started working when I used mod 256. Everything else I sent to Practrand FAILED. I tried the stdin8. I just tested the C version of the Mersenne Twister with Practrand and it failed immediately. The C version of my algorithm will pass Practrand to a TeraByte but the Mersenne Twister is useless.
Post Reply