Here is some example code using the default random number generator
(std::rand()).
I do not have time to explain it, but it can create small differences
between the average
minimum and maximum values of a frequency distribution:
http://codepad.org/ZZhBc65N
__________________________________________________________
#include <iostream>
#include <algorithm>
#include <vector>
#include <climits>
#include <cassert>
#include <cstdlib>
#include <cstring>
#define AN (UCHAR_MAX + 1U)
// crappy little rand...
unsigned int random_byte()
{
double rn = std::rand() / ((double)RAND_MAX);
return (unsigned int)((rn) * (AN - 1U));
}
// stores byte counts...
struct counts
{
unsigned int m_count[AN];
unsigned int m_total;
#define COUNTS_SINIT() { { 0 }, 0 }
void inc(unsigned int n)
{
assert(n < AN);
m_count[n] = m_count[n] + 1;
m_total = m_total + 1;
}
bool inc_if(unsigned int n, unsigned int nmax, unsigned int tmax)
{
assert(n < AN);
if (m_count[n] >= nmax || m_total >= tmax) return false;
inc(n);
return true;
}
void display() const
{
std::cout << m_total << " bytes...\r\n\r\n";
unsigned int total = 0;
double avg_total = 0.0;
double avg_min = 999999999999999.0;
double avg_max = 0.0;
for (unsigned int i = 0; i < AN; ++i)
{
if (m_count[i])
{
double bavg = m_count[i] / (double)m_total;
avg_min = std::min(avg_min, bavg);
avg_max = std::max(avg_max, bavg);
avg_total = avg_total + bavg;
total = total + m_count[i];
std::cout << "[" << i << "] = " << m_count[i] << ", " <<
bavg << "\r\n";
}
}
double avg_diff = avg_max - avg_min;
assert(avg_diff >= 0.0);
std::cout << "total = " << total << "\r\n";
std::cout << "avg_min = " << avg_min << "\r\n";
std::cout << "avg_max = " << avg_max << "\r\n";
std::cout << "avg_diff = " << avg_diff << "\r\n";
std::cout << "avg_total = " << avg_total << "\r\n";
}
};
// crude attempt to get a "flat" frequency distribution...
struct flat_freq
{
counts m_counts;
#define FLAT_FREQ_SINIT() { COUNTS_SINIT() }
void prv_process(unsigned int n, unsigned int nmax, unsigned int tmax)
{
for (unsigned int i = 0; i < n; ++i)
{
// Color Monitor
unsigned int rn = (random_byte() * ((i + 1) * 13)) % AN;
if (! m_counts.inc_if(rn, nmax, tmax))
{
//std::cout << "inc_if failed = \t" << rn << " \r";
}
}
}
unsigned int process(unsigned int n, unsigned int iter = 150)
{
unsigned int i = 0;
unsigned int ndiv = n / AN;
//unsigned int nmax = (ndiv) ? (ndiv + 1U) : (ndiv + 1U);
unsigned int nmax = (ndiv + 0U);
double nmax_real = 0.0;
//unsigned int nrem = ndiv * AN;
//unsigned int nmax = (nrem) ? (ndiv + 1U) : (nrem);
unsigned int iters_total = 0;
while (m_counts.m_total < n)
{
iters_total = iters_total + 1;
double tir = m_counts.m_total / (n - 0.0);
//nmax_real = nmax_real + 1.681; // large
nmax_real = nmax_real + 0.281; // small
for (i = 0; m_counts.m_total < n && i < 128; ++i)
{
unsigned int ptotal = m_counts.m_total;
prv_process(iter, (unsigned int)nmax_real, n);
if (ptotal == m_counts.m_total)
{
std::cout << "infinite loop detected at:" << ptotal <<
"! \r";
break;
}
}
}
std::cout << "\r\n\r\n";
std::cout << "iters_total = " << iters_total << "\r\n";
return i;
}
void display() const
{
m_counts.display();
}
};
int main()
{
{
std::srand(123);
flat_freq ffreq = FLAT_FREQ_SINIT();
unsigned int i = ffreq.process(10003);
std::cout << "i = " << i << "\r\n\r\n";
ffreq.display();
}
std::cout << "\r\n_________________\r\nComplete!\r\n\r\n";
std::cin.get();
return 0;
}
___________________________________________________________
I will explain this further very soon. It has to do with encryption.