summaryrefslogtreecommitdiff
path: root/xs_random.h
diff options
context:
space:
mode:
authorGravatar default2023-06-05 18:29:25 +0200
committerGravatar default2023-06-05 18:29:25 +0200
commitfafdbbf815ea44ca1813a4ab58547d487f6a3bfb (patch)
tree139aeaf983b3b634f4b3bdfa57bb63876bb2cf68 /xs_random.h
parentSome prototype tweaks. (diff)
downloadpenes-snac2-fafdbbf815ea44ca1813a4ab58547d487f6a3bfb.tar.gz
penes-snac2-fafdbbf815ea44ca1813a4ab58547d487f6a3bfb.tar.xz
penes-snac2-fafdbbf815ea44ca1813a4ab58547d487f6a3bfb.zip
Replaced usage of random() with xs_rnd_buf().
Diffstat (limited to 'xs_random.h')
-rw-r--r--xs_random.h87
1 files changed, 87 insertions, 0 deletions
diff --git a/xs_random.h b/xs_random.h
new file mode 100644
index 0000000..3566827
--- /dev/null
+++ b/xs_random.h
@@ -0,0 +1,87 @@
1/* copyright (c) 2022 - 2023 grunfink / MIT license */
2
3#ifndef _XS_RANDOM_H
4
5#define _XS_RANDOM_H
6
7unsigned int xs_rnd_int32_d(unsigned int *seed);
8void *xs_rnd_buf(void *buf, int size);
9
10#ifdef XS_IMPLEMENTATION
11
12#include <stdio.h>
13#include <sys/time.h>
14#include <unistd.h>
15#include <stdlib.h>
16
17unsigned int xs_rnd_int32_d(unsigned int *seed)
18/* returns a deterministic random integer. If seed is NULL, uses a static one */
19{
20 static unsigned int s = 0;
21
22 if (seed == NULL)
23 seed = &s;
24
25 if (*seed == 0) {
26 struct timeval tv;
27
28 gettimeofday(&tv, NULL);
29 *seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
30 }
31
32 /* Linear congruential generator by Numerical Recipes */
33 *seed = (*seed * 1664525) + 1013904223;
34
35 return *seed;
36}
37
38
39void *xs_rnd_buf(void *buf, int size)
40/* fills buf with random data */
41{
42#ifdef __OpenBSD__
43
44 /* available since OpenBSD 2.2 */
45 arc4random_buf(buf, size);
46
47#else
48
49 FILE *f;
50 int done = 0;
51
52 if ((f = fopen("/dev/urandom", "r")) != NULL) {
53 /* fill with great random data from the system */
54 if (fread(buf, size, 1, f) == 1)
55 done = 1;
56
57 fclose(f);
58 }
59
60 if (!done) {
61 /* fill the buffer with poor quality, deterministic data */
62 unsigned int s = 0;
63 unsigned char *p = (unsigned char *)buf;
64 int n = size / sizeof(s);
65
66 /* fill with full integers */
67 while (n--) {
68 xs_rnd_int32_d(&s);
69 p = memcpy(p, &s, sizeof(s)) + sizeof(s);
70 }
71
72 if ((n = size % sizeof(s))) {
73 /* fill the remaining */
74 xs_rnd_int32_d(&s);
75 memcpy(p, &s, n);
76 }
77 }
78
79#endif /* __OpenBSD__ */
80
81 return buf;
82}
83
84
85#endif /* XS_IMPLEMENTATION */
86
87#endif /* XS_RANDOM_H */