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];
}
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
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)