XrdSutRndm.cc

Go to the documentation of this file.
00001 // $Id: XrdSutRndm.cc 30949 2009-11-02 16:37:58Z ganis $
00002 
00003 const char *XrdSutRndmCVSID = "$Id: XrdSutRndm.cc 30949 2009-11-02 16:37:58Z ganis $";
00004 /******************************************************************************/
00005 /*                                                                            */
00006 /*                        X r d S u t R n d m . c c                           */
00007 /*                                                                            */
00008 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
00009 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00010 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00011 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00012 /******************************************************************************/
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 #include <string.h>
00016 #include <sys/types.h>
00017 #include <sys/stat.h>
00018 #include <time.h>
00019 #include <fcntl.h>
00020 #include <errno.h>
00021 
00022 #include <XrdOuc/XrdOucString.hh>
00023 #include <XrdSut/XrdSutRndm.hh>
00024 #include <XrdSut/XrdSutTrace.hh>
00025 
00026 /******************************************************************************/
00027 /*             M a s k s  f o r   A S C I I  c h a r a c t e r s              */
00028 /******************************************************************************/
00029 static kXR_int32 XrdSutCharMsk[4][4] =
00030    { {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe}, // any printable char
00031      {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe},    // letters/numbers  (up/low case)
00032      {0x0, 0x3ff0000, 0x7e, 0x7e},              // hex characters   (up/low case)
00033      {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe} };  // crypt like [a-zA-Z0-9./]
00034 
00035 /******************************************************************************/
00036 /*                                                                            */
00037 /*  Provider of random bunches of bits                                        */
00038 /*                                                                            */
00039 /******************************************************************************/
00040 
00041 bool XrdSutRndm::fgInit = 0;
00042 
00043 //______________________________________________________________________________
00044 bool XrdSutRndm::Init(bool force)
00045 {
00046    // Initialize the random machinery; try using /dev/urandom to avoid
00047    // hanging.
00048    // The bool 'force' can be used to force re-initialization.
00049    EPNAME("Rndm::Init");
00050 
00051    const char *randdev = "/dev/urandom";
00052    bool rc = 0;
00053 
00054    // We do not do it twice 
00055    if (fgInit && !force)
00056       return 1;
00057 
00058    int fd;
00059    unsigned int seed;
00060    if ((fd = open(randdev, O_RDONLY)) != -1) {
00061       DEBUG("taking seed from " <<randdev);
00062       if (read(fd, &seed, sizeof(seed)) == sizeof(seed)) rc = 1;
00063       close(fd);
00064    }
00065    if (rc == 0) {
00066       DEBUG(randdev  <<" not available: using time()");
00067       seed = time(0);   //better use times() + win32 equivalent
00068       rc = 1;
00069    }
00070    srand(seed);
00071 
00072    // Flag as initialized
00073    fgInit = 1;
00074 
00075    return rc;
00076 }
00077 
00078 //______________________________________________________________________________
00079 int XrdSutRndm::GetString(const char *copt, int len, XrdOucString &str)
00080 {
00081    // Static method to fill string str with len random characters.
00082    // Returns 0 if ok, -1 in case of error.
00083    // copt = "Any"      any printable char
00084    //        "LetNum"   letters and numbers  (upper and lower case)
00085    //        "Hex"      hex characters       (upper and lower case)
00086    //        "Crypt"    crypt like           [a-zA-Z0-9./]
00087    //
00088    // (opt is not case sensitive)
00089 
00090    int opt = 0;
00091    if (!strncasecmp(copt,"LetNum",6))
00092       opt = 1;
00093    else if (!strncasecmp(copt,"Hex",3))
00094       opt = 2;
00095    else if (!strncasecmp(copt,"Crypt",5))
00096       opt = 3;
00097 
00098    return XrdSutRndm::GetString(opt,len,str);
00099 }
00100 
00101 //______________________________________________________________________________
00102 int XrdSutRndm::GetString(int opt, int len, XrdOucString &str)
00103 {
00104    // Static method to fill string str with len random characters.
00105    // Returns 0 if ok, -1 in case of error.
00106    // opt = 0      any printable char
00107    //       1      letters and numbers  (upper and lower case)
00108    //       2      hex characters       (upper and lower case)
00109    //       3      crypt like           [a-zA-Z0-9./]
00110    EPNAME("Rndm::GetString");
00111 
00112    const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
00113 
00114    //  Default option 0
00115    if (opt < 0 || opt > 3) {
00116       opt = 0;
00117       DEBUG("unknown option: " <<opt <<": assume 0");
00118    }
00119    DEBUG("enter: len: " <<len <<" (type: " <<cOpt[opt] <<")");
00120 
00121    // Init Random machinery ... if needed
00122    if (!XrdSutRndm::fgInit)
00123       XrdSutRndm::fgInit = XrdSutRndm::Init();
00124 
00125    // randomize
00126    char *buf = new char[len+1];
00127    if (!buf) {
00128       errno = ENOSPC;
00129       return -1;
00130    }
00131 
00132    kXR_int32 k = 0;
00133    kXR_int32 i, j, l, m, frnd;
00134    while (k < len) {
00135       frnd = rand();
00136       for (m = 7; m < 32; m += 7) {
00137          i = 0x7F & (frnd >> m);
00138          j = i / 32;
00139          l = i - j * 32;
00140          if ((XrdSutCharMsk[opt][j] & (1 << l))) {
00141             buf[k] = i;
00142             k++;
00143          }
00144          if (k == len)
00145             break;
00146       }
00147    }
00148 
00149    // null terminated
00150    buf[len] = 0;
00151    DEBUG("got: " <<buf);
00152 
00153    // Fill output
00154    str = buf;
00155    delete[] buf;
00156 
00157    return 0;
00158 }
00159 
00160 //______________________________________________________________________________
00161 char *XrdSutRndm::GetBuffer(int len, int opt)
00162 {
00163    // Static method to fill randomly a buffer.
00164    // Returns the pointer to the buffer if ok, 0 in case of error.
00165    // If opt has one of the following values, the random bytes are
00166    // chosen between the corrsponding subset:
00167    // opt = 0      any printable char
00168    //       1      letters and numbers  (upper and lower case)
00169    //       2      hex characters       (upper and lower case)
00170    //       3      crypt like           [a-zA-Z0-9./]
00171    // The caller is responsible to destroy the buffer
00172    EPNAME("Rndm::GetBuffer");
00173 
00174    DEBUG("enter: len: " <<len);
00175 
00176    // Init Random machinery ... if needed
00177    if (!fgInit) {
00178       Init();
00179       fgInit = 1;
00180    }
00181 
00182    // randomize
00183    char *buf = new char[len];
00184    if (!buf) {
00185       errno = ENOSPC;
00186       return 0;
00187    }
00188 
00189    // Filtering ?
00190    bool filter = (opt >= 0 && opt <= 3);
00191 
00192    kXR_int32 k = 0;
00193    kXR_int32  i, m, frnd, j = 0, l = 0;
00194    while (k < len) {
00195       frnd = rand();
00196       for (m = 0; m < 32; m += 8) {
00197          i = 0xFF & (frnd >> m);
00198          bool keep = 1;
00199          if (filter) {
00200             j = i / 32;
00201             l = i - j * 32;
00202             keep = (XrdSutCharMsk[opt][j] & (1 << l));
00203          }
00204          if (keep) {
00205             buf[k] = i;
00206             k++;
00207          }
00208          if (k == len)
00209             break;
00210       }
00211    }
00212 
00213    return buf;
00214 }
00215 
00216 //______________________________________________________________________________
00217 int XrdSutRndm::GetRndmTag(XrdOucString &rtag)
00218 {
00219    // Static method generating a 64 bit random tag (8 chars in [a-zA-Z0-9./])
00220    // saved in rtag.
00221    // Return 0 in case of success; in case of error, -1 is returned
00222    // and errno set accordingly (see XrdSutRndm::GetString)
00223 
00224    return XrdSutRndm::GetString(3,8,rtag);
00225 }
00226 
00227 
00228 //______________________________________________________________________________
00229 unsigned int XrdSutRndm::GetUInt()
00230 {
00231    // Static method to return an unsigned int.
00232 
00233    // Init Random machinery ... if needed
00234    if (!fgInit) {
00235       Init();
00236       fgInit = 1;
00237    }
00238 
00239    // As simple as this
00240    return rand();
00241 }

Generated on Tue Jul 5 14:47:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1