OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
UserPseudoRandom.c
Go to the documentation of this file.
1
6#include <stdint.h>
7#include <stdio.h>
8#include <time.h>
9
10#ifdef __GNUC__
11uint32_t arc4random(void) __attribute__((weak));
12uint32_t arc4random_uniform(uint32_t upper_bound) __attribute__((weak));
13#endif
14
15// Taken from https://en.wikipedia.org/wiki/Xorshift#Example_implementation
16// I am not positive what is better to use here (especially on Windows).
17// Fortunately we only need something only looking random.
19#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
20 if (arc4random)
21 return arc4random();
22#endif
23
24 static uint32_t state;
25
26 if (!state) {
27 fprintf(stderr, "Warning: arc4random is not available!\n");
28 state = (uint32_t)time(NULL);
29 }
30
31 uint32_t x = state;
32 x ^= x << 13;
33 x ^= x >> 17;
34 x ^= x << 5;
35 state = x;
36 return x;
37}
38
39// Taken from https://opensource.apple.com/source/Libc/Libc-1082.50.1/gen/FreeBSD/arc4random.c
40// Mac OS X 10.6.8 and earlier do not have arc4random_uniform, so we implement one.
42 uint32_t upper_bound = to + 1 - from;
43
44#if defined(__GNUC__) && !defined(__EMSCRIPTEN__)
45 // Prefer native implementation if available.
46 if (arc4random_uniform)
47 return from + arc4random_uniform(upper_bound);
48#endif
49
50 uint32_t r, min;
51
52 if (upper_bound < 2)
53 return from;
54
55#if (ULONG_MAX > 0xffffffffUL)
56 min = 0x100000000UL % upper_bound;
57#else
58 if (upper_bound > 0x80000000)
59 min = 1 + ~upper_bound;
60 else
61 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
62#endif
63
64 for (;;) {
65 r = pseudo_random();
66 if (r >= min)
67 break;
68 }
69
70 return from + r % upper_bound;
71}
UINT16 x
Definition BmfFile.h:83
__attribute__((packed, aligned(1)))
Definition EfiResTool.c:67
#define uint32_t
Definition Ubsan.h:59
uint32_t pseudo_random(void)
uint32_t pseudo_random_between(uint32_t from, uint32_t to)
UINT32 uint32_t