A few smaller tweaks.

This commit is contained in:
Robin Sommer 2011-01-06 19:17:44 -08:00
parent dbca5be43c
commit 6345129eaf
4 changed files with 26 additions and 184 deletions

View file

@ -320,6 +320,7 @@ set(bro_SRCS
PrefixTable.cc PrefixTable.cc
PriorityQueue.cc PriorityQueue.cc
Queue.cc Queue.cc
RandTest.cc
RE.cc RE.cc
RPC.cc RPC.cc
Reassem.cc Reassem.cc

View file

@ -1,9 +1,13 @@
/* /*
Apply various randomness tests to a stream of bytes
Apply various randomness tests to a stream of bytes by John Walker -- September 1996
http://www.fourmilab.ch/random
by John Walker -- September 1996 This software is in the public domain. Permission to use, copy, modify,
http://www.fourmilab.ch/ and distribute this software and its documentation for any purpose and
without fee is hereby granted, without any conditions or restrictions.
This software is provided as is without express or implied warranty.
Modified for Bro by Seth Hall - July 2010 Modified for Bro by Seth Hall - July 2010
*/ */
@ -17,8 +21,8 @@ RandTest::RandTest()
sccfirst = 1; sccfirst = 1;
inmont = mcount = 0; inmont = mcount = 0;
cexp = montex = montey = montepi = sccu0 = scclast = scct1 = scct2 = scct3 = 0.0; cexp = montex = montey = montepi = sccu0 = scclast = scct1 = scct2 = scct3 = 0.0;
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)
{ {
ccount[i] = 0; ccount[i] = 0;
} }
@ -44,7 +48,7 @@ void RandTest::add(void *buf, int bufl)
mcount++; mcount++;
montex = 0; montex = 0;
montey = 0; montey = 0;
for (int mj=0; mj < RT_MONTEN/2; mj++) for (int mj=0; mj < RT_MONTEN/2; mj++)
{ {
montex = (montex * 256.0) + monte[mj]; montex = (montex * 256.0) + monte[mj];
montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj]; montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj];
@ -61,8 +65,8 @@ void RandTest::add(void *buf, int bufl)
sccfirst = 0; sccfirst = 0;
scclast = 0; scclast = 0;
sccu0 = oc; sccu0 = oc;
} }
else else
{ {
scct1 = scct1 + scclast * oc; scct1 = scct1 + scclast * oc;
} }
@ -90,22 +94,22 @@ void RandTest::end(double *r_ent, double *r_chisq,
scc = -100000; scc = -100000;
else else
scc = (totalc * scct1 - scct2) / scc; scc = (totalc * scct1 - scct2) / scc;
/* Scan bins and calculate probability for each bin and /* Scan bins and calculate probability for each bin and
Chi-Square distribution. The probability will be reused Chi-Square distribution. The probability will be reused
in the entropy calculation below. While we're at it, in the entropy calculation below. While we're at it,
we sum of all the data which will be used to compute the we sum of all the data which will be used to compute the
mean. */ mean. */
cexp = totalc / 256.0; /* Expected count per bin */ cexp = totalc / 256.0; /* Expected count per bin */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
double a = ccount[i] - cexp; double a = ccount[i] - cexp;
prob[i] = ((double) ccount[i]) / totalc; prob[i] = ((double) ccount[i]) / totalc;
chisq += (a * a) / cexp; chisq += (a * a) / cexp;
datasum += ((double) i) * ccount[i]; datasum += ((double) i) * ccount[i];
} }
/* Calculate entropy */ /* Calculate entropy */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
@ -114,139 +118,11 @@ void RandTest::end(double *r_ent, double *r_chisq,
ent += prob[i] * rt_log2(1 / prob[i]); ent += prob[i] * rt_log2(1 / prob[i]);
} }
} }
/* Calculate Monte Carlo value for PI from percentage of hits /* Calculate Monte Carlo value for PI from percentage of hits
within the circle */ within the circle */
montepi = 4.0 * (((double) inmont) / mcount); montepi = 4.0 * (((double) inmont) / mcount);
/* Return results through arguments */
*r_ent = ent;
*r_chisq = chisq;
*r_mean = datasum / totalc;
*r_montepicalc = montepi;
*r_scc = scc;
}
/*
Apply various randomness tests to a stream of bytes
by John Walker -- September 1996
http://www.fourmilab.ch/
Modified for Bro by Seth Hall - July 2010
*/
#include <RandTest.h>
RandTest::RandTest()
{
totalc = 0;
mp = 0;
sccfirst = 1;
inmont = mcount = 0;
cexp = montex = montey = montepi = sccu0 = scclast = scct1 = scct2 = scct3 = 0.0;
for (int i = 0; i < 256; i++)
{
ccount[i] = 0;
}
}
void RandTest::add(void *buf, int bufl)
{
unsigned char *bp = (unsigned char*)buf;
int oc;
while (bufl-- > 0)
{
oc = *bp++;
ccount[oc]++; /* Update counter for this bin */
totalc++;
/* Update inside / outside circle counts for Monte Carlo
computation of PI */
monte[mp++] = oc; /* Save character for Monte Carlo */
if (mp >= RT_MONTEN) /* Calculate every RT_MONTEN character */
{
mp = 0;
mcount++;
montex = 0;
montey = 0;
for (int mj=0; mj < RT_MONTEN/2; mj++)
{
montex = (montex * 256.0) + monte[mj];
montey = (montey * 256.0) + monte[(RT_MONTEN / 2) + mj];
}
if (montex*montex + montey*montey <= RT_INCIRC)
{
inmont++;
}
}
/* Update calculation of serial correlation coefficient */
if (sccfirst)
{
sccfirst = 0;
scclast = 0;
sccu0 = oc;
}
else
{
scct1 = scct1 + scclast * oc;
}
scct2 = scct2 + oc;
scct3 = scct3 + (oc * oc);
scclast = oc;
oc <<= 1;
}
}
void RandTest::end(double *r_ent, double *r_chisq,
double *r_mean, double *r_montepicalc, double *r_scc)
{
int i;
double ent, chisq, scc, datasum;
ent = 0.0; chisq = 0.0; scc = 0.0; datasum = 0.0;
double prob[256]; /* Probabilities per bin for entropy */
/* Complete calculation of serial correlation coefficient */
scct1 = scct1 + scclast * sccu0;
scct2 = scct2 * scct2;
scc = totalc * scct3 - scct2;
if (scc == 0.0)
scc = -100000;
else
scc = (totalc * scct1 - scct2) / scc;
/* Scan bins and calculate probability for each bin and
Chi-Square distribution. The probability will be reused
in the entropy calculation below. While we're at it,
we sum of all the data which will be used to compute the
mean. */
cexp = totalc / 256.0; /* Expected count per bin */
for (i = 0; i < 256; i++)
{
double a = ccount[i] - cexp;
prob[i] = ((double) ccount[i]) / totalc;
chisq += (a * a) / cexp;
datasum += ((double) i) * ccount[i];
}
/* Calculate entropy */
for (i = 0; i < 256; i++)
{
if (prob[i] > 0.0)
{
ent += prob[i] * rt_log2(1 / prob[i]);
}
}
/* Calculate Monte Carlo value for PI from percentage of hits
within the circle */
montepi = 4.0 * (((double) inmont) / mcount);
/* Return results through arguments */ /* Return results through arguments */
*r_ent = ent; *r_ent = ent;
*r_chisq = chisq; *r_chisq = chisq;

View file

@ -21,7 +21,7 @@ class RandTest {
void add(void *buf, int bufl); void add(void *buf, int bufl);
void end(double *r_ent, double *r_chisq, double *r_mean, void end(double *r_ent, double *r_chisq, double *r_mean,
double *r_montepicalc, double *r_scc); double *r_montepicalc, double *r_scc);
private: private:
long ccount[256]; /* Bins to count occurrences of values */ long ccount[256]; /* Bins to count occurrences of values */
long totalc; /* Total bytes counted */ long totalc; /* Total bytes counted */
@ -29,40 +29,6 @@ class RandTest {
int sccfirst; int sccfirst;
unsigned int monte[RT_MONTEN]; unsigned int monte[RT_MONTEN];
long inmont, mcount; long inmont, mcount;
double cexp, montex, montey, montepi, double cexp, montex, montey, montepi,
sccu0, scclast, scct1, scct2, scct3; sccu0, scclast, scct1, scct2, scct3;
}; };
#include <math.h>
#define log2of10 3.32192809488736234787
/* RT_LOG2 -- Calculate log to the base 2 */
static double rt_log2(double x)
{
return log2of10 * log10(x);
}
#define RT_MONTEN 6 /* Bytes used as Monte Carlo
co-ordinates. This should be no more
bits than the mantissa of your "double"
floating point type. */
// RT_INCIRC = pow(pow(256.0, (double) (RT_MONTEN / 2)) - 1, 2.0);
#define RT_INCIRC 281474943156225.0
class RandTest {
public:
RandTest();
void add(void *buf, int bufl);
void end(double *r_ent, double *r_chisq, double *r_mean,
double *r_montepicalc, double *r_scc);
private:
long ccount[256]; /* Bins to count occurrences of values */
long totalc; /* Total bytes counted */
int mp;
int sccfirst;
unsigned int monte[RT_MONTEN];
long inmont, mcount;
double cexp, montex, montey, montepi,
sccu0, scclast, scct1, scct2, scct3;
};

View file

@ -3201,7 +3201,7 @@ function disable_event_group%(group: string%) : any
%%{ %%{
#include <RandTest.h> #include <RandTest.h>
static map<BroString, RandTest*> entropy_states; static map<BroString, RandTest*> entropy_states;
%%} %%}
function find_entropy%(data: string%): entropy_test_result function find_entropy%(data: string%): entropy_test_result
%{ %{
@ -3241,13 +3241,13 @@ function entropy_test_add%(index: any, data: string%): bool
%{ %{
BroString* s = convert_index_to_string(index); BroString* s = convert_index_to_string(index);
int status = 0; int status = 0;
if ( entropy_states.count(*s) > 0 ) if ( entropy_states.count(*s) > 0 )
{ {
entropy_states[*s]->add((char*) data->Bytes(), data->Len()); entropy_states[*s]->add((char*) data->Bytes(), data->Len());
status = 1; status = 1;
} }
delete s; delete s;
return new Val(status, TYPE_BOOL); return new Val(status, TYPE_BOOL);
%} %}
@ -3258,11 +3258,10 @@ function entropy_test_finish%(index: any%): entropy_test_result
double montepi, scc, ent, mean, chisq; double montepi, scc, ent, mean, chisq;
montepi = scc = ent = mean = chisq = 0.0; montepi = scc = ent = mean = chisq = 0.0;
RecordVal* ent_result = new RecordVal(entropy_test_result); RecordVal* ent_result = new RecordVal(entropy_test_result);
if ( entropy_states.count(*s) > 0 ) if ( entropy_states.count(*s) > 0 )
{ {
RandTest *rt; RandTest *rt = entropy_states[*s];
rt = entropy_states[*s];
rt->end(&ent, &chisq, &mean, &montepi, &scc); rt->end(&ent, &chisq, &mean, &montepi, &scc);
entropy_states.erase(*s); entropy_states.erase(*s);
delete rt; delete rt;