Chi-squared test for randomness

Share your advanced PureBasic knowledge/code with the community.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Chi-squared test for randomness

Post by Keya »

hello i have ported the Chi-squared test from John Walker's ENT randomness test suite, here is the main part from his original code:

Code: Select all

    cexp = totalc / (binary ? 2.0 : 256.0);  /* Expected count per bin */
    for (i = 0; i < (binary ? 2 : 256); i++) {
       double a = ccount[i] - cexp;       
       prob[i] = ((double) ccount[i]) / totalc;       
       chisq += (a * a) / cexp;
       datasum += ((double) i) * ccount[i];
    }
and my Purebasic port, output appears to match that of the original ent.exe:

Code: Select all

EnableExplicit
 
Procedure.d ChiSquared(*buf.Ascii, size)
  Protected i, a.d, chisq.d 
  Protected cexp = size / 256.0
  Dim ccount(255)               
  For i = 1 To size
    ccount(*buf\a)+1:    *buf+1
  Next
  For i = 0 To 255
    a.d = ccount(i) - cexp
    chisq + (a * a) / cexp
  Next i
  ProcedureReturn chisq       
EndProcedure
simple tests:

Code: Select all

IncludeFile("ChiSquared.pbi")
 
;Test 1 - Cryptographically random data (value should be small)
Define size=4096*64
Define *buf = AllocateMemory(size)
If OpenCryptRandom() And *buf
  CryptRandomData(*buf, size):  CloseCryptRandom()
EndIf
Debug "Crypto-random: " + StrD(ChiSquared(*buf, size))
FreeMemory(*buf)


;Test 2 - Our own executable file with mostly non-random data (value should be large)
size = FileSize(ProgramFilename())
*buf = AllocateMemory(size)
ReadFile(0,ProgramFilename(), #PB_File_SharedRead|#PB_File_SharedWrite)
ReadData(0,*buf,size)
CloseFile(0)
Debug "Non-random: " + StrD(ChiSquared(*buf, size))
FreeMemory(*buf)