๐Ÿ“ฆ filterpaper / prng

๐Ÿ“„ jsf16.c ยท 66 lines
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/* Copyright (C) 2021 @filterpaper
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/* Simple implementation of Bob Jenkin's small fast 16-bit PRNG
   http://burtleburtle.net/bob/rand/smallprng.html
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>

typedef uint16_t u2;
typedef struct { u2 a; u2 b; u2 c; u2 d; } ranctx_t;

#define rot(x,k) (((x)<<(k))|((x)>>(16-(k))))
u2 ranval(ranctx_t *x) {
	u2 e = x->a - rot(x->b, 13);
	x->a = x->b ^ rot(x->c, 8);
	x->b = x->c + x->d;
	x->c = x->d + e;
	return x->d = e + x->a;
}

void raninit(ranctx_t *x, u2 seed) {
	x->a = seed*random();
	x->b = x->c = x->d = seed;

	for (u2 i=seed; i>0; --i) { (void)ranval(x); }
}

int main(int argc, char **argv) {
	ranctx_t rng;

	// Init using OSX random function as seed
	srandom(time(NULL));
	raninit(&rng, random());

	if (argc>1) { // Binary stream output
		u2 val16;
		while (1) {
			val16 = ranval(&rng);
			fwrite((void*) &val16, sizeof(val16), 1, stdout);
		}
	} else {
		for (uint8_t i=0; i<16; ++i) {
			printf("0x%04hx 0x%04hx 0x%04hx 0x%04hx\n", ranval(&rng), ranval(&rng), ranval(&rng), ranval(&rng));
		}
	}

	return 0;
}