Serenity Operating System
1/*
2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Platform.h>
10#include <AK/StdLibExtras.h>
11#include <AK/Types.h>
12
13#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID)
14# include <stdlib.h>
15#endif
16
17#if defined(__unix__)
18# include <unistd.h>
19#endif
20
21#if defined(AK_OS_MACOS)
22# include <sys/random.h>
23#endif
24
25#if defined(AK_OS_WINDOWS)
26# include <stdlib.h>
27#endif
28
29namespace AK {
30
31inline void fill_with_random([[maybe_unused]] void* buffer, [[maybe_unused]] size_t length)
32{
33#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID)
34 arc4random_buf(buffer, length);
35#elif defined(OSS_FUZZ)
36#elif defined(__unix__) or defined(AK_OS_MACOS)
37 [[maybe_unused]] int rc = getentropy(buffer, length);
38#else
39 char* char_buffer = static_cast<char*>(buffer);
40 for (size_t i = 0; i < length; i++) {
41 char_buffer[i] = rand();
42 }
43#endif
44}
45
46template<typename T>
47inline T get_random()
48{
49 T t;
50 fill_with_random(&t, sizeof(T));
51 return t;
52}
53
54u32 get_random_uniform(u32 max_bounds);
55
56template<typename Collection>
57inline void shuffle(Collection& collection)
58{
59 // Fisher-Yates shuffle
60 for (size_t i = collection.size() - 1; i >= 1; --i) {
61 size_t j = get_random_uniform(i + 1);
62 AK::swap(collection[i], collection[j]);
63 }
64}
65
66}
67
68#if USING_AK_GLOBALLY
69using AK::fill_with_random;
70using AK::get_random;
71using AK::get_random_uniform;
72using AK::shuffle;
73#endif