76 lines
2.1 KiB
C++
76 lines
2.1 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
|
|
|
#ifndef BITCOIN_RANDOM_H
|
|
#define BITCOIN_RANDOM_H
|
|
|
|
#include "uint256.h"
|
|
|
|
#include <functional>
|
|
#include <stdint.h>
|
|
|
|
/**
|
|
* Functions to gather random data via the libsodium CSPRNG
|
|
*/
|
|
void GetRandBytes(unsigned char* buf, size_t num);
|
|
uint64_t GetRand(uint64_t nMax);
|
|
int GetRandInt(int nMax);
|
|
uint256 GetRandHash();
|
|
|
|
/**
|
|
* Identity function for MappedShuffle, so that elements retain their original order.
|
|
*/
|
|
int GenIdentity(int n);
|
|
|
|
/**
|
|
* Rearranges the elements in the range [first,first+len) randomly, assuming
|
|
* that gen is a uniform random number generator. Follows the same algorithm as
|
|
* std::shuffle in C++11 (a Durstenfeld shuffle).
|
|
*
|
|
* The elements in the range [mapFirst,mapFirst+len) are rearranged according to
|
|
* the same permutation, enabling the permutation to be tracked by the caller.
|
|
*
|
|
* gen takes an integer n and produces a uniform random output in [0,n).
|
|
*/
|
|
template <typename RandomAccessIterator, typename MapRandomAccessIterator>
|
|
void MappedShuffle(RandomAccessIterator first,
|
|
MapRandomAccessIterator mapFirst,
|
|
size_t len,
|
|
std::function<int(int)> gen)
|
|
{
|
|
for (size_t i = len-1; i > 0; --i) {
|
|
auto r = gen(i+1);
|
|
assert(r >= 0);
|
|
assert(r <= i);
|
|
std::swap(first[i], first[r]);
|
|
std::swap(mapFirst[i], mapFirst[r]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fast randomness source. This is seeded once with secure random data, but
|
|
* is completely deterministic and insecure after that.
|
|
* This class is not thread-safe.
|
|
*/
|
|
class FastRandomContext {
|
|
public:
|
|
explicit FastRandomContext(bool fDeterministic=false);
|
|
|
|
uint32_t rand32() {
|
|
Rz = 36969 * (Rz & 65535) + (Rz >> 16);
|
|
Rw = 18000 * (Rw & 65535) + (Rw >> 16);
|
|
return (Rw << 16) + Rz;
|
|
}
|
|
|
|
bool randbool() {
|
|
return rand32() & 1;
|
|
}
|
|
|
|
uint32_t Rz;
|
|
uint32_t Rw;
|
|
};
|
|
|
|
#endif // BITCOIN_RANDOM_H
|