Changeset View
Changeset View
Standalone View
Standalone View
src/random.h
| Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
| class FastRandomContext { | class FastRandomContext { | ||||
| private: | private: | ||||
| bool requires_seed; | bool requires_seed; | ||||
| ChaCha20 rng; | ChaCha20 rng; | ||||
| uint64_t bitbuf; | uint64_t bitbuf; | ||||
| int bitbuf_size; | int bitbuf_size; | ||||
| void RandomSeed(); | void RandomSeed() noexcept; | ||||
| void FillBitBuffer() { | void FillBitBuffer() noexcept { | ||||
| bitbuf = rand64(); | bitbuf = rand64(); | ||||
| bitbuf_size = 64; | bitbuf_size = 64; | ||||
| } | } | ||||
| public: | public: | ||||
| explicit FastRandomContext(bool fDeterministic = false) noexcept; | explicit FastRandomContext(bool fDeterministic = false) noexcept; | ||||
| /** Initialize with explicit seed (only for testing) */ | /** Initialize with explicit seed (only for testing) */ | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | uint64_t randrange(uint64_t range) noexcept { | ||||
| uint64_t ret = randbits(bits); | uint64_t ret = randbits(bits); | ||||
| if (ret <= range) { | if (ret <= range) { | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** Generate random bytes. */ | /** Generate random bytes. */ | ||||
| template <typename B = uint8_t> std::vector<B> randbytes(size_t len) { | template <typename B = uint8_t> | ||||
| std::vector<B> randbytes(size_t len) noexcept { | |||||
| std::vector<B> ret(len); | std::vector<B> ret(len); | ||||
| fillrand(MakeWritableByteSpan(ret)); | fillrand(MakeWritableByteSpan(ret)); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| /** Fill a byte Span with random bytes. */ | /** Fill a byte Span with random bytes. */ | ||||
| void fillrand(Span<std::byte> output); | void fillrand(Span<std::byte> output) noexcept; | ||||
| /** Generate a random 32-bit integer. */ | /** Generate a random 32-bit integer. */ | ||||
| uint32_t rand32() noexcept { return randbits(32); } | uint32_t rand32() noexcept { return randbits(32); } | ||||
| /** generate a random uint160. */ | /** generate a random uint160. */ | ||||
| uint160 rand160() noexcept { | uint160 rand160() noexcept { | ||||
| uint160 ret; | uint160 ret; | ||||
| fillrand(MakeWritableByteSpan(ret)); | fillrand(MakeWritableByteSpan(ret)); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| /** generate a random uint256. */ | /** generate a random uint256. */ | ||||
| uint256 rand256() noexcept { | uint256 rand256() noexcept { | ||||
| uint256 ret; | uint256 ret; | ||||
| fillrand(MakeWritableByteSpan(ret)); | fillrand(MakeWritableByteSpan(ret)); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| /** Generate a random boolean. */ | /** Generate a random boolean. */ | ||||
| bool randbool() noexcept { return randbits(1); } | bool randbool() noexcept { return randbits(1); } | ||||
| /** Return the time point advanced by a uniform random duration. */ | /** Return the time point advanced by a uniform random duration. */ | ||||
| template <typename Tp> | template <typename Tp> | ||||
| Tp rand_uniform_delay(const Tp &time, typename Tp::duration range) { | Tp rand_uniform_delay(const Tp &time, | ||||
| typename Tp::duration range) noexcept { | |||||
| using Dur = typename Tp::duration; | using Dur = typename Tp::duration; | ||||
| Dur dur{range.count() > 0 | Dur dur{range.count() > 0 | ||||
| ? /* interval [0..range) */ Dur{randrange(range.count())} | ? /* interval [0..range) */ Dur{randrange(range.count())} | ||||
| : range.count() < 0 | : range.count() < 0 | ||||
| ? /* interval (range..0] */ -Dur{randrange(-range.count())} | ? /* interval (range..0] */ -Dur{randrange(-range.count())} | ||||
| : | : | ||||
| /* interval [0..0] */ Dur{0}}; | /* interval [0..0] */ Dur{0}}; | ||||
| return time + dur; | return time + dur; | ||||
| } | } | ||||
| // Compatibility with the C++11 UniformRandomBitGenerator concept | // Compatibility with the C++11 UniformRandomBitGenerator concept | ||||
| typedef uint64_t result_type; | typedef uint64_t result_type; | ||||
| static constexpr uint64_t min() { return 0; } | static constexpr uint64_t min() noexcept { return 0; } | ||||
| static constexpr uint64_t max() { | static constexpr uint64_t max() noexcept { | ||||
| return std::numeric_limits<uint64_t>::max(); | return std::numeric_limits<uint64_t>::max(); | ||||
| } | } | ||||
| inline uint64_t operator()() noexcept { return rand64(); } | inline uint64_t operator()() noexcept { return rand64(); } | ||||
| }; | }; | ||||
| /** | /** | ||||
| * More efficient than using std::shuffle on a FastRandomContext. | * More efficient than using std::shuffle on a FastRandomContext. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines | |||||