OSDN Git Service

Implemented randomness functions.
[mutilities/MUtilities.git] / src / Global.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
21
22 #if _MSC_VER
23 #define _CRT_RAND_S 1
24 #endif
25
26 #include <MUtils/Global.h>
27
28 //CRT
29 #include <cstdlib>
30 #include <ctime>
31 #include <process.h>
32
33 ///////////////////////////////////////////////////////////////////////////////
34 // Random Support
35 ///////////////////////////////////////////////////////////////////////////////
36
37 //Robert Jenkins' 96 bit Mix Function
38 static unsigned int mix_function(const unsigned int x, const unsigned int y, const unsigned int z)
39 {
40         unsigned int a = x;
41         unsigned int b = y;
42         unsigned int c = z;
43         
44         a=a-b;  a=a-c;  a=a^(c >> 13);
45         b=b-c;  b=b-a;  b=b^(a << 8 ); 
46         c=c-a;  c=c-b;  c=c^(b >> 13);
47         a=a-b;  a=a-c;  a=a^(c >> 12);
48         b=b-c;  b=b-a;  b=b^(a << 16);
49         c=c-a;  c=c-b;  c=c^(b >> 5 );
50         a=a-b;  a=a-c;  a=a^(c >> 3 );
51         b=b-c;  b=b-a;  b=b^(a << 10);
52         c=c-a;  c=c-b;  c=c^(b >> 15);
53
54         return a ^ b ^ c;
55 }
56
57 void MUtils::seed_rand(void)
58 {
59         qsrand(mix_function(clock(), time(NULL), _getpid()));
60 }
61
62 quint32 MUtils::next_rand32(void)
63 {
64         quint32 rnd = 0xDEADBEEF;
65
66 #ifdef _CRT_RAND_S
67         if(rand_s(&rnd) == 0)
68         {
69                 return rnd;
70         }
71 #endif //_CRT_RAND_S
72
73         for(size_t i = 0; i < sizeof(quint32); i++)
74         {
75                 rnd = (rnd << 8) ^ qrand();
76         }
77
78         return rnd;
79 }
80
81 quint64 MUtils::next_rand64(void)
82 {
83         return (quint64(next_rand32()) << 32) | quint64(next_rand32());
84 }
85
86 QString MUtils::rand_str(const bool &bLong)
87 {
88         if(!bLong)
89         {
90                 return QString::number(next_rand64(), 16).rightJustified(16, QLatin1Char('0'));
91         }
92         return QString("%1%2").arg(rand_str(false), rand_str(false));
93 }