fliptag 3.1 - A Pseudo Random Number Generator (Verified)

4 posts in this topic

#1 ·  Posted (edited)


Here's a small PRNG called fliptag. It uses mostly linear math and its state can be completely kept within only 6 "registers" and the implementation is only 27 lines of code long.


I ran ent, DIEHARD and the NIST.GOV test suite against it (though I only did all the tests for one fixed seed). I re-ran ent with this, because this implementation has a system-time dependent seed.

fliptag has 4 seed parameters, of which 3 are optional. The first one is the genesis seed and determines the starting state. Because this seed is very sensitive to small decimal changes, the current system tickcount (modified) is used in addition to the current system time. (AutoIts MT uses time(NULL))

Here are some sample ent results from the AutoIt test suite, which generates a 1,5 MB file from random bytes:




1. Entropy

A truly random sequence has an entropy value of 8.0. This is however not achievable by any software PRNG. Both PRNG are on par and have a very respectable entropy value.

2. Compression

A dense file (with high entropy) cannot be compressed. Both PRNG achieve perfect scores.

3. Chi²

The chi-square test is the most commonly used test for the randomness of data, and is extremely sensitive to errors in pseudorandom sequence generators. The chi-square distribution is calculated for the stream of bytes in the file and expressed as an absolute number and a percentage which indicates how frequently a truly random sequence would exceed the value calculated. We interpret the percentage as the degree to which the sequence tested is suspected of being non-random. If the percentage is greater than 99% or less than 1%, the sequence is almost certainly not random. If the percentage is between 99% and 95% or between 1% and 5%, the sequence is suspect. Percentages between 90% and 95% and 5% and 10% indicate the sequence is “almost suspect”.

Both PRNGs achieve very good results. For comparison, Unix' rand() achieves a catastrophic 0.01, a Park & Miller PRNG will achieve roughly 97.5, while a truly - physical - random sequence will result in a Chi² score of about 40.9. 

4. Arithmetic mean value

Truly random sequences have an arithmetic mean value of exactly 127.5 (0xFF * 0.5). Both PRNG achieve near-perfect scores.

5. Monte Carlo Pi

Each successive sequence of six bytes is used as 24 bit X and Y co-ordinates within a square. If the distance of the randomly-generated point is less than the radius of a circle inscribed within the square, the six-byte sequence is considered a “hit”. The percentage of hits can be used to calculate the value of Pi. For very large streams (this approximation converges very slowly), the value will approach the correct value of Pi if the sequence is close to random. 

Considering that even radioactive decay (true physical randomness) will not achieve better results than both PRNGs. So the scores are almost perfect.

6. Serial Correlation

This quantity measures the extent to which each byte in the file depends upon the previous byte. For random sequences, this value (which can be positive or negative) will, of course, be close to zero. A non-random byte stream such as a C program will yield a serial correlation coefficient on the order of 0.5. Wildly predictable data such as uncompressed bitmaps will exhibit serial correlation coefficients approaching 1.

Both PRNGs achieve very good results.





Edited by minx
1 person likes this

I will answer every single PM, and you are free to ask anything anytime.

Share this post

Link to post
Share on other sites

"Get a random number between {0..255} inclusive."

Awesome work! Thank you for sharing, minx.

How can we increase the scope beyond 255, maybe 2,000, for example?

Thank you.

Share this post

Link to post
Share on other sites

"Get a random number between {0..255} inclusive."

Awesome work! Thank you for sharing, minx.

How can we increase the scope beyond 255, maybe 2,000, for example?

Thank you.

​Well fliptag returns bytes. Basically you want to construct a value which can be expressed as [0,1) Then just multiply with your left and right limits :) . For example, if the value turns out to be 0 <= n < 1, which is the most common output, the calculation could be done like:

$result = Floor(YOURFUNCTION() * (1 + $high - $low)) + $low


I will answer every single PM, and you are free to ask anything anytime.

Share this post

Link to post
Share on other sites

#4 ·  Posted (edited)

Here's an example. The resolution was increased to 1.525902189669642e-5 to allow random floats :).

; Replica of AutoIts Random()
ConsoleWrite("-> " & _fliptag_random(1, 10, 1) & @LF)
ConsoleWrite("-> " & _fliptag_random(1, 10, 0) & @LF)

Func _fliptag_random($Min = 0, $Max = 1, $Flag = 0)
   Local $fFloat = (_fliptag_flip() + BitAND(($_flip[1] + $_flip[2]), 0x00FFFF)) / 0x00FFFF
   Return $Flag ? Floor($fFloat * (1 + $Max - $Min)) + $Min : $fFloat * (1 + $Max - $Min) + $Min


Edited by minx

I will answer every single PM, and you are free to ask anything anytime.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • JustinZandee
      By JustinZandee
      I need a random string generator which creates 15 letters/numbers.
      How can I make that?
    • Anas
      By Anas
      I've this script (removed unrelated parts) that generate a set of random chars for a password. It gets launched from a network share by Task Scheduler at a specific time for all PC's, then it relaunches itself from the local drive.
      Global $LocalToolsDir = @ProgramFilesDir & '\Tools' Start() Func Start() If Not StringInStr(@ScriptFullPath, $LocalToolsDir, 2) Then Exit RunLocaly() Sleep(Random(1, 1800, 1) * 1000) $NewPass = GeneratePass() EndFunc Func GeneratePass() Local $Pass For $i = 1 to 8 $R = Random(0,1.5) If $R > 1 Then $Chr = Random(0,9,1) ElseIf $R < 0.5 Then $Chr = Chr(Random(Asc("A"), Asc("Z"), 1)) Else $Chr = Chr(Random(Asc("a"), Asc("z"), 1)) Endif $Pass &= $Chr Next Return $Pass EndFunc Func RunLocaly() Local $Run = 1, $LocalApp = $LocalToolsDir & '\' & @ScriptName If Not FileExists($LocalApp) Then $Run = FileCopy(@ScriptFullPath, $LocalToolsDir, 1 + 8) If $Run Then Run($LocalApp, $LocalToolsDir) EndFunc  
      The problem is that many PC's ends up with the same password(s).
      e.g. 10 PC's have (abc123) as a Password, and another 10 have this (def456)
      Any idea why?
    • Dequality
      By Dequality
      Got a simple question is it possible to have lets say 10 functions and use the random function to randomly pick one of them? If so could anyone please make a tiny example?
      Tyvm in advance 
    • CarlD
      By CarlD
      I'm a command-line kind of guy, and I write scripts primarily for myself.  Since many websites nowadays require strong passwords, I thought I'd write a simple password generator in AutoIt. I know that AutoIt mavens have written more elaborate pw generators; I offer mine for what it's worth. The compiled script, GenPass.exe, can be downloaded here. See below for Help text and source. Enjoy!
      2017-05-06: Default password changed to variable length of 13-22 characters; argument "1" no longer supported
                            When compiled as GenPW.exe, password is sent directly to the clipboard, no message box unless password generation fails.
      2017-05-05: Correction to bypass password generation if argument is ?|H|h
      2017-05-03: Added special argument 1 to generate a password of variable length (10-18 characters) including two (2) separator characters
      2017-05-02: Added option /S to set a (persistent) randomization seed
      GenPass.exe|GenPW.exe -- CLD rev. 2017-05-06
      Generate a strong password and save it to the Windows clipboard
      Note: GenPW.exe has the same functionality as GenPass.exe, but
            sends the generated password directly to the clipboard.
            No message box is displayed (unless password generation fails).
      "Strong" means that the password contains random combinations of
      alphnumeric characters, including at least one uppercase letter
      (A-N,P-Z), one lowercase letter (a-k,m-z), and one number (0-9).
      (Generated passwords do not use uppercase O or lowercase l as
      these characters are easily confused with the numbers 0 and 1.)
      The length of the password is up to you (see Usage, below),
      but needless to say, the longer, the stronger.
      By default, GenPass generates a strong password of between 13
      and 22 characters that includes two of the following separator
      characters: $%&()*+,-./:;@[]_. Alternatively, you can supply a
      command-line argument in which any number n from 1 to 9 stands
      for a random sequence of alphanumeric characters of length
      n, and any other character stands for itself. Thus, you can
      include fixed words and other characters, such as separators,
      in the generated password. Spaces in the argument are converted
      to underscores. Here are some examples:
      Usage             Sample output
      -----             -------------
      GenPass           MqU26A*6dS-53r8
      GenPass 9         frdhPYDs9
      GenPass 58        weoXYHKxDI1uQ
      GenPass 5.5       UfA6j.43VBB
      GenPass 3-4-3     0I0-6gq4-njc
      GenPass 5,3.7     I2FSR,tRZ.fjeIsFy
      GenPass 3)5(3     UMf)m8513(CBq
      GenPass 3[haha]3  yLa[haha]P3y
      GenPass Yes way5  Yes_way1BsUh
      Seed Option (/S)
      Adding switch /S to the command-line argument causes GenPass to
      set a seed for the random generation of password characters. A
      bare /S sets a randomized seed which is written to disk in a file
      named GenPass.rnd; this seed is used for all subsequent launches
      of GenPass with the bare /S option. Alternatively, you can specify
      a seed (range -2^31 to 2^31-1) on the command line with /S [seed].
      Here are some examples:
      GenPass /S
      GenPass /S 33.3333
      GenPass 5,5,5 /S
      GenPass 5,5,5 /S 33.3333
      Note that any subsequent launch of GenPass without the /S option
      will cause GenPass.rnd to be deleted.
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=GenPass.exe #AutoIt3Wrapper_UseUpx=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs GENPASS.AU3 -- AutoIt v3 CLD rev.2017-05-05 ------------------ Generate a strong password and save it to the clipboard >> Command GenPass ? for detailed help << ------------------------------------------------------- #ce #include <Clipboard.au3> #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> AutoItSetOption("WinTitleMatchMode", -4) FileInstall ("d:\path\GenPass.htm", @ScriptDir & "\GenPass.htm", $FC_OVERWRITE) ; Template/Seed Local $sTemp = "" Local $bSeed = False, $fSeed=False If $CmdLine[0] Then $sTemp = $CmdLineRaw If $CmdLine[$CmdLine[0]] = "/s" Then $bSeed = True $sTemp = StringTrimRight($sTemp, 2) $sTemp = StringStripWS($sTemp, $STR_STRIPTRAILING) EndIf If $CmdLine[$CmdLine[0] - 1] = "/s" Then $bSeed = True $fSeed = $CmdLine[$CmdLine[0]] $sTemp = StringTrimRight($sTemp, 3 + StringLen($fSeed)) $sTemp = StringStripWS($sTemp, $STR_STRIPTRAILING) EndIf EndIf If Not $sTemp Then $sTemp = "8" If $sTemp = "1" Then $aSeps = StringSplit("#$%&()*+,-./:;@[]_", "") $sTemp = String(Random(3,6,1)) & $aSeps[Random(1,$aSeps[0],1)] & _ String(Random(2,4,1)) & $aSeps[Random(1,$aSeps[0],1)] & _ String(Random(3,6,1)) EndIf $sFn = @ScriptDir&"\GenPass.rnd" If $bSeed Then If Not $fSeed Then If Not FileExists($sFn) Then $fSeed = Random(-1.999^31,1.999^31,0) $h=FileOpen($sFn,2) If $h > -1 Then FileWrite($h,$fSeed) FileClose($h) Else Exit MsgBox($MB_ICONWARNING, @ScriptName, "Error opening " & $sFn) EndIf Else $h=FileOpen($sFn) If $h > -1 Then $fSeed=FileRead($h) FileClose($h) Else Exit MsgBox($MB_ICONWARNING, @ScriptName, "Error opening " & $sFn) EndIf EndIf EndIf SRandom($fSeed) Else If FileExists($sFn) Then FileDelete($sFn) EndIf ; Show help If StringInStr("?Hh", $sTemp) Then If WinExists("[REGEXPTITLE:GenPass.exe:.*]") Then WinActivate("[REGEXPTITLE:GenPass.exe:.*]") Else ShellExecute(@ScriptDir & "\GenPass.htm") EndIf Exit EndIf ; Main $sTemp = StringReplace($sTemp, " ", "_") $iC = 1 While $iC < 10001 $sPW = GenPW($sTemp) If $sPW Then ClipPut($sPW) If Not StringInStr (@ScriptName, "GenPW") Then _ MsgBox($MB_ICONINFORMATION, @ScriptName, $sPW & _ " saved to clipboard" & @CRLF & @CRLF & _ @ScriptName & " ? shows detailed help") Exit Else $iC += 1 EndIf WEnd Exit MsgBox($MB_ICONWARNING, @ScriptName, "Password generation failed!") ;------------------------------- Func GenPw($sTemplate) Local $aIn = StringSplit($sTemplate,"") Local $sOut = "" Local $sABC = _ "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789" Local $aAB = StringSplit($sABC, "") Local $bUC = 0, $bLC = 0, $bNR = 0 For $i = 1 To $aIn[0] If Int($aIn[$i]) Then $iK = $aIn[$i] For $j = 1 To $iK $iR = Random(1, $aAB[0],1) Select Case StringInStr("0123456789", $aAB[$iR]) $bNR = 1 Case StringInStr("ABCDEFGHIJKLMNPQRSTUVWXYZ", _ $aAB[$iR], $STR_CASESENSE) $bUC = 1 Case StringInStr("abcdefghijklmnpqrstuvwxyz", _ $aAB[$iR], $STR_CASESENSE) $bLC = 1 EndSelect $sOut &= $aAB[$iR] Next Else $sOut &= $aIn[$i] EndIf Next If ($bUC And $bLC And $bNR) Then Return $sOut Else Return 0 EndIf EndFunc  
    • hcI
      By hcI
      Hello everyone !
      I've made a little function who return random characters for everyone who would need it.. It's my first function so please have some mercy.
      And if you have some suggestions.. don't hesitate !
      and I made a AutoIt HelpFile that looks like others helpfiles, I hope you'll enjoy !
      The function :  RandomLetter.au3
      The helpfile : RandomLetter.html  (in HTML please !)
      Et pour les anglophobes, voilà l'aide en français : RandomLetter.fr.html (French version of the helpfile)
      Thanks, hcI