using cellular automata to generate random numbers
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned char cells[sizeof(unsigned long)];
} rand_t;
#define UNSIGNED_LONG_TWO_SLOTS (sizeof(unsigned long) / 2)
#define RAND_T_LOAD(rd, seed) do { \
unsigned char* reader = (unsigned char*)(&(seed)); \
unsigned ir; \
for(ir = 0; ir < sizeof(unsigned long); ir++) rd->cells[ir] = reader[ir]; \
} while (0)
typedef struct {
unsigned char match[2];
unsigned char result;
} rule_t;
/**
* Rule matching table
*/
static const rule_t RULE_MATCH[] = {
{{0, 0}, 1},
{{0, 1}, 0},
{{1, 1}, 2},
{{0, 2}, 1},
{{1, 2}, 2},
{{2, 0}, 0},
{{2, 1}, 1},
{{2, 2}, 0},
};
static const size_t RULE_MATCH_COUNT = sizeof(RULE_MATCH) / sizeof(rule_t);
static const unsigned char RULE_DEFAULT = 0;
static void rand_clean(rand_t* cells)
{
cells->cells[0] = 0;
cells->cells[1] = 0;
cells->cells[2] = 0;
cells->cells[3] = 0;
cells->cells[4] = 0;
cells->cells[5] = 0;
cells->cells[6] = 0;
cells->cells[7] = 0;
}
static rand_t rand_generation(const rand_t* cells)
{
rand_t next_gen;
rand_clean(&next_gen);
unsigned i;
for(i=0; i < sizeof(unsigned long) - 1; i++)
{
unsigned j;
for(j=0; j < RULE_MATCH_COUNT;j++)
{
if(cells->cells[i] == RULE_MATCH[j].match[0] && cells->cells[i + 1] == RULE_MATCH[j].match[1])
{
next_gen.cells[i] = RULE_MATCH[j].result;
break;
}
}
}
return next_gen;
}
void rand_print(const rand_t* cells)
{
unsigned i;
for(i=0; i < sizeof(unsigned long) ; i++)
{
printf("(%u) ", cells->cells[i]);
}
printf(" as u64: %lu", *(unsigned long*)(cells->cells));
putc('\n', stdout);
}
int main(int argc, char const *argv[])
{
rand_t foo = {{2, 1, 0, 0, 2, 0, 1, 2}};
rand_print(&foo);
unsigned i;
for(i = 0; i < 50; i++)
{
foo = rand_generation(&foo);
rand_print(&foo);
}
return 0;
}
// example results
/**
(2) (1) (0) (0) (2) (0) (1) (2) as u64: 144396671642501378
(1) (0) (1) (1) (0) (0) (2) (0) as u64: 562949970264065
(0) (0) (2) (0) (1) (1) (0) (0) as u64: 1103806726144
(1) (1) (0) (0) (2) (0) (1) (0) as u64: 281483566645505
(2) (0) (1) (1) (0) (0) (0) (0) as u64: 16842754
(0) (0) (2) (0) (1) (1) (1) (0) as u64: 282578783436800
(1) (1) (0) (0) (2) (2) (0) (0) as u64: 2207613190401
(2) (0) (1) (1) (0) (0) (1) (0) as u64: 281474993553410
(0) (0) (2) (0) (1) (0) (0) (0) as u64: 4295098368
(1) (1) (0) (0) (0) (1) (1) (0) as u64: 282574488338689
(2) (0) (1) (1) (0) (2) (0) (0) as u64: 2199040098306
(0) (0) (2) (0) (1) (0) (1) (0) as u64: 281479271809024
(1) (1) (0) (0) (0) (0) (0) (0) as u64: 257
(2) (0) (1) (1) (1) (1) (1) (0) as u64: 282578800148482
(0) (0) (2) (2) (2) (2) (0) (0) as u64: 2207646875648
(1) (1) (0) (0) (0) (0) (1) (0) as u64: 281474976710913
(2) (0) (1) (1) (1) (0) (0) (0) as u64: 4311810050
(0) (0) (2) (2) (0) (1) (1) (0) as u64: 282574522023936
(1) (1) (0) (0) (0) (2) (0) (0) as u64: 2199023255809
(2) (0) (1) (1) (1) (0) (1) (0) as u64: 281479288520706
(0) (0) (2) (2) (0) (0) (0) (0) as u64: 33685504
(1) (1) (0) (0) (1) (1) (1) (0) as u64: 282578783305985
(2) (0) (1) (0) (2) (2) (0) (0) as u64: 2207613255682
(0) (0) (0) (1) (0) (0) (1) (0) as u64: 281474993487872
(1) (1) (0) (0) (1) (0) (0) (0) as u64: 4294967553
(2) (0) (1) (0) (0) (1) (1) (0) as u64: 282574488403970
(0) (0) (0) (1) (0) (2) (0) (0) as u64: 2199040032768
(1) (1) (0) (0) (1) (0) (1) (0) as u64: 281479271678209
(2) (0) (1) (0) (0) (0) (0) (0) as u64: 65538
(0) (0) (0) (1) (1) (1) (1) (0) as u64: 282578800082944
(1) (1) (0) (2) (2) (2) (0) (0) as u64: 2207646744833
(2) (0) (1) (0) (0) (0) (1) (0) as u64: 281474976776194
(0) (0) (0) (1) (1) (0) (0) (0) as u64: 4311744512
(1) (1) (0) (2) (0) (1) (1) (0) as u64: 282574521893121
(2) (0) (1) (0) (0) (2) (0) (0) as u64: 2199023321090
(0) (0) (0) (1) (1) (0) (1) (0) as u64: 281479288455168
(1) (1) (0) (2) (0) (0) (0) (0) as u64: 33554689
(2) (0) (1) (0) (1) (1) (1) (0) as u64: 282578783371266
(0) (0) (0) (0) (2) (2) (0) (0) as u64: 2207613190144
(1) (1) (1) (1) (0) (0) (1) (0) as u64: 281474993553665
(2) (2) (2) (0) (1) (0) (0) (0) as u64: 4295098882
(0) (0) (0) (0) (0) (1) (1) (0) as u64: 282574488338432
(1) (1) (1) (1) (0) (2) (0) (0) as u64: 2199040098561
(2) (2) (2) (0) (1) (0) (1) (0) as u64: 281479271809538
(0) (0) (0) (0) (0) (0) (0) (0) as u64: 0
(1) (1) (1) (1) (1) (1) (1) (0) as u64: 282578800148737
(2) (2) (2) (2) (2) (2) (0) (0) as u64: 2207646876162
(0) (0) (0) (0) (0) (0) (1) (0) as u64: 281474976710656
(1) (1) (1) (1) (1) (0) (0) (0) as u64: 4311810305
(2) (2) (2) (2) (0) (1) (1) (0) as u64: 282574522024450
(0) (0) (0) (0) (0) (2) (0) (0) as u64: 2199023255552
*/