-
Notifications
You must be signed in to change notification settings - Fork 14
/
random.cpp
120 lines (93 loc) · 2.79 KB
/
random.cpp
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
OOPoker
Copyright (c) 2010 Lode Vandevenne
All rights reserved.
This file is part of OOPoker.
OOPoker is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OOPoker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OOPoker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "random.h"
#include "os.h"
#include <iostream>
#if defined(_WIN32)
#include <windows.h>
unsigned int getRandomUint()
{
unsigned int r;
HMODULE hLib=LoadLibrary("ADVAPI32.DLL");
if(hLib) {
BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
(BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036");
if(pfn) {
char buff[4];
ULONG ulCbBuff = sizeof(buff);
if(pfn(buff,ulCbBuff)) {
// use buff full of random goop
r = buff[0] + 256 * buff[1] + 256 * 256 * buff[2] + 256 * 256 * 256 * buff[3];
}
}
FreeLibrary(hLib);
}
return r;
}
// TODO: OS_UNKNOWN may not have /dev/urandom, provide alternative implementation
#elif defined(OS_LINUX) || defined(OS_UNKNOWN)
#include <string>
#include <fstream>
unsigned int getRandomUint()
{
unsigned int r;
static std::string filename = "/dev/urandom";
static std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
if(!file) {
std::cerr << "no /dev/urandom found! Need a random source to operate. Quitting program." << std::endl;
std::exit(1);
}
file.read((char*)(&r), sizeof(r));
return r;
}
#endif
double getRandom()
{
return getRandomUint() / 4294967296.0;
}
int getRandom(int low, int high)
{
return getRandomUint() % (high - low + 1) + low;
}
static unsigned int m_w = 1;
static unsigned int m_z = 2;
//"Multiply-With-Carry" generator of G. Marsaglia
unsigned int getRandomUintFast()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; //32-bit result
}
void seedRandomFast(unsigned int seed1, unsigned int seed2)
{
if(seed1 == 0) seed1 = 1;
if(seed2 == 0) seed2 = 1;
m_w = seed1;
m_z = seed2;
}
void seedRandomFastWithRandomSlow()
{
seedRandomFast(getRandomUint(), getRandomUint());
}
double getRandomFast()
{
return getRandomUintFast() / 4294967296.0;
}
int getRandomFast(int low, int high)
{
return getRandomUintFast() % (high - low + 1) + low;
}