1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#ifdef _WIN32
#define DllExport __declspec(dllexport)
#else
#define DllExport
#endif
#include <stdio.h>
#include "random.h"
#define ONE_MASK 0x0001
#define MOD_2_MASK 0x1
#define MOD_32_MASK 0x3F
#define MOD_256_MASK 0x0FF
/* 32-bit unsigned max. */
#define UINT_MAX 4294967295U
static unsigned char line[2][256] ;
static unsigned char curr_line = 0 ;
/*
* Generate <n_bit> uniformly random bits from a 1-D cellular automata.
* The automata used is rule 30
*(using Wolfram's classification of cellular automata).
*/
unsigned int rule_30_automata(unsigned char n_bit)
{
unsigned char next_line, k ;
unsigned short int i, prev, next ;
unsigned int num = 0 ;
n_bit &= MOD_32_MASK ;
for(k=0; k<n_bit; k++) {
next_line = (curr_line + 1) & MOD_2_MASK ;
for(i=0; i<256; i++) {
prev = (i + 255) & MOD_256_MASK ;
next = (i + 1) & MOD_256_MASK ;
if (( line[curr_line][prev] & ~ line[curr_line][i] &
~ line[curr_line][next] ) ||
( ~ line[curr_line][prev] & line[curr_line][i] &
line[curr_line][next] ) ||
( ~ line[curr_line][prev] & line[curr_line][i] &
~ line[curr_line][next] ) ||
( ~ line[curr_line][prev] & ~ line[curr_line][i] &
line[curr_line][next] )) {
line[next_line][i] = 1 ;
} else {
line[next_line][i] = 0 ;
}
}
curr_line = next_line ;
num <<= 1 ;
num |= line[curr_line][128] ;
}
return( num ) ;
}
void init_rule_30_automata(unsigned int n)
{
unsigned char i ;
unsigned int m = n ;
for(i=0; i<32; i++) {
line[curr_line][112 + i] = m & MOD_2_MASK ;
m >>= 1 ;
}
rule_30_automata(32) ;
rule_30_automata(32) ;
rule_30_automata(32) ;
rule_30_automata(32) ;
rule_30_automata(32) ;
rule_30_automata(32) ;
}
#define RAND() ( rule_30_automata(32) )
#define URAND() ( rule_30_automata(32) / (1.0 * UINT_MAX) )
#define BRAND() ( rule_30_automata(1) )
DllExport unsigned int random(void)
{
return(RAND()) ;
}
DllExport double urand(void)
{
return(URAND()) ;
}
DllExport unsigned int brand(void)
{
return(BRAND()) ;
}
DllExport void rand_init(int seed)
{
init_rule_30_automata(seed) ;
}
|