12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /* copyright (c) 2022 - 2024 grunfink et al. / MIT license */
- #ifndef _XS_RANDOM_H
- #define _XS_RANDOM_H
- unsigned int xs_rnd_int32_d(unsigned int *seed);
- void *xs_rnd_buf(void *buf, int size);
- #ifdef XS_IMPLEMENTATION
- #include <stdio.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <stdlib.h>
- unsigned int xs_rnd_int32_d(unsigned int *seed)
- /* returns a deterministic random integer. If seed is NULL, uses a static one */
- {
- static unsigned int s = 0;
- if (seed == NULL)
- seed = &s;
- if (*seed == 0) {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- *seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
- }
- /* Linear congruential generator by Numerical Recipes */
- *seed = (*seed * 1664525) + 1013904223;
- return *seed;
- }
- void *xs_rnd_buf(void *buf, int size)
- /* fills buf with random data */
- {
- #ifdef __OpenBSD__
- /* available since OpenBSD 2.2 */
- arc4random_buf(buf, size);
- #else
- FILE *f;
- int done = 0;
- if ((f = fopen("/dev/urandom", "r")) != NULL) {
- /* fill with great random data from the system */
- if (fread(buf, size, 1, f) == 1)
- done = 1;
- fclose(f);
- }
- if (!done) {
- /* fill the buffer with poor quality, deterministic data */
- unsigned int s = 0;
- unsigned char *p = (unsigned char *)buf;
- int n = size / sizeof(s);
- /* fill with full integers */
- while (n--) {
- xs_rnd_int32_d(&s);
- memcpy(p, &s, sizeof(s));
- p += sizeof(s);
- }
- if ((n = size % sizeof(s))) {
- /* fill the remaining */
- xs_rnd_int32_d(&s);
- memcpy(p, &s, n);
- }
- }
- #endif /* __OpenBSD__ */
- return buf;
- }
- #endif /* XS_IMPLEMENTATION */
- #endif /* XS_RANDOM_H */
|