1 /*
2    mkvmerge -- utility for splicing together matroska files
3    from component media subtypes
4 
5    Distributed under the GPL v2
6    see the file COPYING for details
7    or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8 
9    random number generating functions
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #include "common/common_pch.h"
15 
16 #include <cstdlib>
17 #include <random>
18 
19 #include "common/fs_sys_helpers.h"
20 #include "common/random.h"
21 
22 namespace {
23 
24 std::unique_ptr<std::mt19937_64> s_generator;
25 std::uniform_int_distribution<uint8_t> s_uint8_distribution;
26 std::uniform_int_distribution<uint32_t> s_uint32_distribution;
27 std::uniform_int_distribution<uint64_t> s_uint64_distribution;
28 
29 }
30 
31 void
init(std::optional<uint64_t> seed)32 random_c::init(std::optional<uint64_t> seed) {
33   s_generator = std::make_unique<std::mt19937_64>();
34 
35   if (!seed) {
36 #if defined(SYS_WINDOWS)
37     // mingw's implementation of std::random_device yields deterministic
38     // sequences, unfortunately.
39     seed = mtx::sys::get_current_time_millis();
40 
41 #else
42     seed = std::random_device()();
43 #endif
44   }
45 
46   std::srand(*seed);
47   s_generator->seed(*seed);
48 }
49 
50 void
generate_bytes(void * destination,size_t num_bytes)51 random_c::generate_bytes(void *destination,
52                          size_t num_bytes) {
53   auto dst = static_cast<unsigned char *>(destination);
54 
55   for (int i = 0; i < static_cast<int>(num_bytes); ++i, ++dst)
56     *dst = s_uint8_distribution(*s_generator);
57 }
58 
59 uint8_t
generate_8bits()60 random_c::generate_8bits() {
61   return s_uint8_distribution(*s_generator);
62 }
63 
64 uint32_t
generate_32bits()65 random_c::generate_32bits() {
66   return s_uint32_distribution(*s_generator);
67 }
68 
69 uint64_t
generate_64bits()70 random_c::generate_64bits() {
71   return s_uint64_distribution(*s_generator);
72 }
73