ROOT logo
#include "hseed.h"
#include "TSystem.h"
#include "TMath.h"
#include "TInetAddress.h"
#include "TDatime.h"

#include <iostream>
#include <iomanip>
#include <unistd.h>


using namespace std;

//_HADES_CLASS_DESCRIPTION
/////////////////////////////////////////////////////////////////////////////
//
// HSeed
//
// Helper class for random sedd generation on batch farm
// for the available options see the constructor of the class
//
////////////////////////////////////////////////////////////////////////////

ClassImp(HSeed)


HSeed::HSeed(Int_t method,Int_t fallback,Int_t fixedSeed, Bool_t noBlock)
{
    //  method;           0 (default) : /dev/random,
    //                    1 : TRandom3 (local) with systime ,
    //                    2 : TRandom3 (local) with systime + processid + iplast,
    //                    3 : like 1 but gRandom,
    //                    4 : like 2 but gRandom,
    //                    5 : fixed (needs seed to be set)
    //  fallback          case /dev/random is not available : default 2
    //  fixedSeed  ;   //   default -1  used when method 5 is active
    //  noBlock           :  kTRUE switch /dev/radom to /dev/urandom  to avoid blocking (less randomness!)
    //
    //
    //  Int_t     getFixedSeed();     //   default -1
    //  Int_t     getInitialSeed();   //   default -1, stores the seed input gRandom
    //  Int_t     getFirstSeed();     //   default -1, stores the first seed generated
    //  TString   getHostname();      //   hostname of execution
    //  UInt_t    getAddress();       //   4 * 8bit address fields
    //  UInt_t    getPid();           //   process id



    fNoBlock = noBlock;

    fHostname = gSystem->HostName();
    fAddress  = getIP();
    fPid      = getPid();

    frandom = 0;

    if(method < 0 || method > 5)
    {
	Error("HSeed()","method %i :  method has to be 1 ... 5. Use 0 instead.",method);
	fMethod = 0;
    } else {
	fMethod = method;
    }

    if(fMethod != 0 ) fallback = fMethod;

    if(fallback < 1 || fallback > 4)
    {
	Error("HSeed()","fallback %i :  method has to be 1 ... 4. Use 2 instead.",fallback);
	fFallBack = 2;
    } else {
	fFallBack = fallback;
    }

    fFirstSeed   =-1;
    fInitialSeed =-1;
    fFixedSeed   =-1;
    fFileHandle  =-1;

    if(fNoBlock) fFileHandle = open("/dev/urandom", O_RDONLY);
    else         fFileHandle = open("/dev/random" , O_RDONLY);
    if(fFileHandle < 0){
	if(fNoBlock) Error("HSeed()","Could not open /dev/urandom for reading : will take numbers from TRandom3 ( method 2)");
	else         Error("HSeed()","Could not open /dev/random for reading : will take numbers from TRandom3 ( method 2)");
	fMethod   = fallback;
	fFallBack = fallback; // not used
	fFileHandle =-1;
    }

    TDatime datime;
    UInt_t t      = datime.Get();
    Int_t  iplast = getIPPart(0);


    if        (fMethod == 0) {
	if     (fFallBack == 1) {fGenerator.SetSeed(t);                       frandom = &fGenerator; fInitialSeed = t;}
	else if(fFallBack == 2) {fGenerator.SetSeed(t+fPid*1000+iplast*1000); frandom = &fGenerator; fInitialSeed = t+fPid*1000+iplast*1000;}
	else if(fFallBack == 3) {gRandom  ->SetSeed(t);                       frandom = gRandom;     fInitialSeed = t;}
	else if(fFallBack == 4) {gRandom  ->SetSeed(t+fPid*1000+iplast*1000); frandom = gRandom;     fInitialSeed = t+fPid*1000+iplast*1000;}

    } else {

	if     (fMethod == 1) {fGenerator.SetSeed(t);                       frandom = &fGenerator;fInitialSeed = t;}
	else if(fMethod == 2) {fGenerator.SetSeed(t+fPid*1000+iplast*1000); frandom = &fGenerator;fInitialSeed = t+fPid*1000+iplast*1000;}
	else if(fMethod == 3) {gRandom  ->SetSeed(t);                       frandom = gRandom;    fInitialSeed = t;}
	else if(fMethod == 4) {gRandom  ->SetSeed(t+fPid*1000+iplast*1000); frandom = gRandom;    fInitialSeed = t+fPid*1000+iplast*1000;}

	if(fMethod == 5){
	    if(fixedSeed < 0 ) { Error("HSeed()","Option fixedSeed used, but seed is negative! will use Abs()"); }
	    fFixedSeed   = TMath::Abs(fixedSeed);
	    fInitialSeed = fFixedSeed;
	    fFirstSeed   = fFixedSeed;
	}

    }

}
HSeed::~HSeed()
{
    if(fFileHandle!=-1){
	close(fFileHandle);
    }
    fFileHandle=-1;

}

UInt_t HSeed::getPid()
{
    // returns the current process id
    return gSystem->GetPid();
}

UInt_t HSeed::getIP()
{
    // gets the ip address of the host from the system
    TString hostname     = gSystem->HostName();
    TInetAddress address = gSystem->GetHostByName(hostname.Data());
    return address.GetAddress();
}

UInt_t HSeed::getIPPart(UInt_t field)
{
    // return the 4 segmentent ip address (field ==0 the lowest bytes)
    if(field > 3) {
	Error("getIPPart()","address field has to be 0,1,2 or 3 . Take lowest bytes instead.");
	field=0;
    }
    return (0xFF)&(fAddress>>field*8);
}

Int_t HSeed::getSeed()
{
    // generate a new seed from the selected source
    Int_t rndNum =-1;
    if        (fMethod == 0)
    {
	Int_t ret = read(fFileHandle, &rndNum, sizeof(rndNum));
	if(ret < 0){
	    if(fNoBlock) Error("getSeed()"," Could not read from /dev/urandom : will take numbers from fallback");
	    else         Error("getSeed()"," Could not read from /dev/random : will take numbers from fallback");
	    close(fFileHandle);
	    fFileHandle = -1;
	    fMethod     = fFallBack;
	} else {
	    while(rndNum<0){   // make sure they are in rang of int
		ret = read(fFileHandle, &rndNum, sizeof(rndNum));
	    }
	    if(fFirstSeed == -1) fFirstSeed = rndNum;
	    return rndNum;
	}
    } else if (fMethod > 0 && fMethod < 5) {
	while(rndNum<0) {
	    rndNum = frandom->Rndm()*(kMaxInt-1);
	}
	if(fFirstSeed == -1) fFirstSeed = rndNum;
	return rndNum;
    }
    else if(fMethod == 5 ){
	return fFixedSeed;
    }
  return -1;
}

void  HSeed::print()
{
    // print all params in 1 line
    cout<<"HSeed : "<<fHostname<<", ip : "<<Form("%i.%i.%i.%i",getIPPart(3),getIPPart(2),getIPPart(1),getIPPart(0))<<", pid :" <<fPid
	<<", method : "  <<setw(4) <<fMethod
	<<", fallback : "<<setw(4) <<fFallBack
	<<", first : "   <<setw(10)<<fFirstSeed
	<<", init : "    <<setw(10)<<fInitialSeed
	<<", fixed : "   <<setw(10)<<fFixedSeed
	<<endl;

}

 hseed.cc:1
 hseed.cc:2
 hseed.cc:3
 hseed.cc:4
 hseed.cc:5
 hseed.cc:6
 hseed.cc:7
 hseed.cc:8
 hseed.cc:9
 hseed.cc:10
 hseed.cc:11
 hseed.cc:12
 hseed.cc:13
 hseed.cc:14
 hseed.cc:15
 hseed.cc:16
 hseed.cc:17
 hseed.cc:18
 hseed.cc:19
 hseed.cc:20
 hseed.cc:21
 hseed.cc:22
 hseed.cc:23
 hseed.cc:24
 hseed.cc:25
 hseed.cc:26
 hseed.cc:27
 hseed.cc:28
 hseed.cc:29
 hseed.cc:30
 hseed.cc:31
 hseed.cc:32
 hseed.cc:33
 hseed.cc:34
 hseed.cc:35
 hseed.cc:36
 hseed.cc:37
 hseed.cc:38
 hseed.cc:39
 hseed.cc:40
 hseed.cc:41
 hseed.cc:42
 hseed.cc:43
 hseed.cc:44
 hseed.cc:45
 hseed.cc:46
 hseed.cc:47
 hseed.cc:48
 hseed.cc:49
 hseed.cc:50
 hseed.cc:51
 hseed.cc:52
 hseed.cc:53
 hseed.cc:54
 hseed.cc:55
 hseed.cc:56
 hseed.cc:57
 hseed.cc:58
 hseed.cc:59
 hseed.cc:60
 hseed.cc:61
 hseed.cc:62
 hseed.cc:63
 hseed.cc:64
 hseed.cc:65
 hseed.cc:66
 hseed.cc:67
 hseed.cc:68
 hseed.cc:69
 hseed.cc:70
 hseed.cc:71
 hseed.cc:72
 hseed.cc:73
 hseed.cc:74
 hseed.cc:75
 hseed.cc:76
 hseed.cc:77
 hseed.cc:78
 hseed.cc:79
 hseed.cc:80
 hseed.cc:81
 hseed.cc:82
 hseed.cc:83
 hseed.cc:84
 hseed.cc:85
 hseed.cc:86
 hseed.cc:87
 hseed.cc:88
 hseed.cc:89
 hseed.cc:90
 hseed.cc:91
 hseed.cc:92
 hseed.cc:93
 hseed.cc:94
 hseed.cc:95
 hseed.cc:96
 hseed.cc:97
 hseed.cc:98
 hseed.cc:99
 hseed.cc:100
 hseed.cc:101
 hseed.cc:102
 hseed.cc:103
 hseed.cc:104
 hseed.cc:105
 hseed.cc:106
 hseed.cc:107
 hseed.cc:108
 hseed.cc:109
 hseed.cc:110
 hseed.cc:111
 hseed.cc:112
 hseed.cc:113
 hseed.cc:114
 hseed.cc:115
 hseed.cc:116
 hseed.cc:117
 hseed.cc:118
 hseed.cc:119
 hseed.cc:120
 hseed.cc:121
 hseed.cc:122
 hseed.cc:123
 hseed.cc:124
 hseed.cc:125
 hseed.cc:126
 hseed.cc:127
 hseed.cc:128
 hseed.cc:129
 hseed.cc:130
 hseed.cc:131
 hseed.cc:132
 hseed.cc:133
 hseed.cc:134
 hseed.cc:135
 hseed.cc:136
 hseed.cc:137
 hseed.cc:138
 hseed.cc:139
 hseed.cc:140
 hseed.cc:141
 hseed.cc:142
 hseed.cc:143
 hseed.cc:144
 hseed.cc:145
 hseed.cc:146
 hseed.cc:147
 hseed.cc:148
 hseed.cc:149
 hseed.cc:150
 hseed.cc:151
 hseed.cc:152
 hseed.cc:153
 hseed.cc:154
 hseed.cc:155
 hseed.cc:156
 hseed.cc:157
 hseed.cc:158
 hseed.cc:159
 hseed.cc:160
 hseed.cc:161
 hseed.cc:162
 hseed.cc:163
 hseed.cc:164
 hseed.cc:165
 hseed.cc:166
 hseed.cc:167
 hseed.cc:168
 hseed.cc:169
 hseed.cc:170
 hseed.cc:171
 hseed.cc:172
 hseed.cc:173
 hseed.cc:174
 hseed.cc:175
 hseed.cc:176
 hseed.cc:177
 hseed.cc:178
 hseed.cc:179
 hseed.cc:180
 hseed.cc:181
 hseed.cc:182
 hseed.cc:183
 hseed.cc:184
 hseed.cc:185
 hseed.cc:186
 hseed.cc:187
 hseed.cc:188
 hseed.cc:189
 hseed.cc:190
 hseed.cc:191
 hseed.cc:192
 hseed.cc:193
 hseed.cc:194
 hseed.cc:195
 hseed.cc:196