1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
#include <iostream>
#include <random>
#include <array>
#include <numeric>
using namespace std;
#if defined(__linux__) || defined(linux) || defined(__linux)
#include <fstream>
size_t sysrandom(void* dst, size_t dstlen) {
char* buffer = reinterpret_cast<char*>(dst);
std::ifstream stream("/dev/urandom", stream.binary);
stream.read(buffer, dstlen);
return dstlen;
}
#elif defined(_WIN32)
#include <wincrypt.h>
bool acquire_context(HCRYPTPROV *ctx) {
if (!CryptAcquireContext(ctx, 0, 0, PROV_RSA_FULL, 0))
return CryptAcquireContext(ctx, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET);
return true;
}
size_t sysrandom(void* dst, size_t dstlen) {
HCRYPTPROV ctx;
if (!acquire_context(&ctx))
throw std::runtime_error("Unable to initialize Win32 crypt library.");
BYTE* buffer = reinterpret_cast<BYTE*>(dst);
if(!CryptGenRandom(ctx, dstlen, buffer))
throw std::runtime_error("Unable to generate random bytes.");
if (!CryptReleaseContext(ctx, 0))
throw std::runtime_error("Unable to release Win32 crypt library.");
return dstlen;
}
#endif
template<typename T> // can use for mt19937 or mt19937_64
void seed_mt19937(T& rnd) {
array<typename T::result_type, T::state_size> state;
sysrandom(state.begin(), state.size() * sizeof(typename T::result_type));
seed_seq s(state.begin(), state.end());
rnd.seed(s);
}
const int Size = 100, Choose = 30;
int main() {
mt19937 rnd;
seed_mt19937(rnd);
vector<int> v(Size);
iota(v.begin(), v.end(), 0);
for (int i = Size, j = 0; j < 30 && --i > 0; ++j) {
swap(v[i], v[uniform_int_distribution<>(0, i)(rnd)]);
cout << v[i] << ' ';
}
cout << '\n';
}
|