Changeset 167 for cpp/common


Ignore:
Timestamp:
03/11/14 14:41:32 (11 years ago)
Author:
sz
Message:

win32: add more randomness from uuid

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/random.h

    r122 r167  
    66#include <time.h> //time()
    77#ifdef MULTITHREADED
    8 #include "threads.h"
     8 #include "threads.h"
    99#endif
    1010#ifdef LINUX
    11 #include <unistd.h>
    12 #include <sys/stat.h>
    13 #include <fcntl.h>
     11 #include <unistd.h>
     12 #include <sys/stat.h>
     13 #include <fcntl.h>
     14#endif
     15#ifdef _WIN32
     16 #define _WINSOCKAPI_ //http://stackoverflow.com/questions/1372480/c-redefinition-header-files
     17 #include <rpc.h> //UUID
     18 #pragma comment(lib, "Rpcrt4.lib")
    1419#endif
    1520
     
    2126{
    2227private:
    23         static const unsigned int length=624;
    24         static const unsigned int bitMask_32=0xffffffff;
    25         static const unsigned int bitPow_31=1<<31;
    26         static const unsigned int MAXVALUE=0xffffffff;
     28        static const unsigned int length = 624;
     29        static const unsigned int bitMask_32 = 0xffffffff;
     30        static const unsigned int bitPow_31 = 1 << 31;
     31        static const unsigned int MAXVALUE = 0xffffffff;
    2732        unsigned int counter; //only used in randomize(). uninitialized is OK
    2833#ifdef MULTITHREADED
     
    3641        {
    3742#ifdef MULTITHREADED
    38                 pthread_mutex_init(&lock,NULL);
     43                pthread_mutex_init(&lock, NULL);
    3944#endif
    40                 mt=new unsigned int[length];
     45                mt = new unsigned int[length];
    4146                setSeed(seed);
    4247        }
     
    4752                pthread_mutex_lock(&lock);
    4853#endif
    49                 idx=0;
    50                 mt[0]=seed;
    51                 for(unsigned int i=1;i<length;i++)
    52                         mt[i]=(1812433253*(mt[i-1]^(mt[i-1]>>30))+i)&bitMask_32;
     54                idx = 0;
     55                mt[0] = seed;
     56                for (unsigned int i = 1; i < length; i++)
     57                        mt[i] = (1812433253 * (mt[i - 1] ^ (mt[i - 1] >> 30)) + i)&bitMask_32;
    5358#ifdef MULTITHREADED
    5459                pthread_mutex_unlock(&lock);
     
    5661        }
    5762
    58         inline unsigned int randomize()
     63        unsigned int randomize()
    5964        {
    6065                unsigned int seed;
     66                //for ms visual, could use http://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx
    6167#ifdef LINUX
    6268                int fd=open("/dev/urandom",O_RDONLY);
     
    7076                {
    7177                        counter++;
    72                         seed=time(NULL);              //time (seconds)
    73                         seed^=counter;                //incremented value, possibly randomly initialized
    74                         seed^=(unsigned int)&counter; //memory address
     78                        seed = time(NULL);              //time (seconds); could use hi-res timer but then we would depend on common/timer.h
     79                        seed ^= counter;                //incremented value, possibly randomly initialized
     80                        seed ^= (unsigned int)&counter; //memory address
    7581                }
     82#ifdef _WIN32 //add more randomness from uuid
     83                UUID uuid;
     84                ::UuidCreate(&uuid);
     85                seed ^= uuid.Data1^uuid.Data2^uuid.Data3^uuid.Data4[0];
     86#endif
    7687                setSeed(seed);
    7788                return seed;
     
    8394                pthread_mutex_lock(&lock);
    8495#endif
    85                 if (idx==0) gen();
    86                 unsigned int y=mt[idx];
    87                 idx=(idx+1)%length;
     96                if (idx == 0) gen();
     97                unsigned int y = mt[idx];
     98                idx = (idx + 1) % length;
    8899#ifdef MULTITHREADED
    89100                pthread_mutex_unlock(&lock);
    90101#endif
    91                 y^= y>>11;
    92                 y^=(y<< 7)&2636928640U;
    93                 y^=(y<<15)&4022730752U;
    94                 y^= y>>18;
     102                y ^= y >> 11;
     103                y ^= (y << 7) & 2636928640U;
     104                y ^= (y << 15) & 4022730752U;
     105                y ^= y >> 18;
    95106                return y;
    96107        }
     
    98109        inline double getDouble() // [0,1)
    99110        {
    100                 return double(getUint32())/((LONGLONG)(MAXVALUE)+1);
     111                return double(getUint32()) / ((LONGLONG)(MAXVALUE)+1);
    101112        }
    102113
    103114        inline void gen()
    104115        {
    105                 for(unsigned int i=0;i<length;i++)
     116                for (unsigned int i = 0; i < length; i++)
    106117                {
    107                         unsigned int y=(mt[i]&bitPow_31)+(mt[(i+1)%length]&(bitPow_31-1));
    108                         mt[i]=mt[(i+397)%length]^(y>>1);
    109                         if(y%2) mt[i]^=2567483615U;
     118                        unsigned int y = (mt[i] & bitPow_31) + (mt[(i + 1) % length] & (bitPow_31 - 1));
     119                        mt[i] = mt[(i + 397) % length] ^ (y >> 1);
     120                        if (y % 2) mt[i] ^= 2567483615U;
    110121                }
    111122                return;
     
    117128        }
    118129};
    119 
Note: See TracChangeset for help on using the changeset viewer.