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 64-bit PRNG
http://burtleburtle.net/bob/rand/smallprng.html
*/
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
typedef uint64_t u8;
typedef struct { u8 a; u8 b; u8 c; u8 d; } ranctx_t;
#define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
u8 ranval(ranctx_t *x) {
u8 e = x->a - rot(x->b, 7);
x->a = x->b ^ rot(x->c, 13);
x->b = x->c + rot(x->d, 37);
x->c = x->d + e;
return x->d = e + x->a;
}
void raninit(ranctx_t *x, u8 seed) {
x->a = seed*random();
x->b = x->c = x->d = seed;
for (uint16_t 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()*random());
if (argc>1) { // Binary stream output
u8 val64;
while (1) {
val64 = ranval(&rng);
fwrite((void*) &val64, sizeof(val64), 1, stdout);
}
} else {
for (uint8_t i=0; i<16; ++i) {
printf("0x%016llx 0x%016llx 0x%016llx 0x%016llx\n", ranval(&rng), ranval(&rng), ranval(&rng), ranval(&rng));
}
}
return 0;
}