1 /******************************************************************************* 2 copyright: Copyright (c) 2008. Fawzi Mohamed 3 license: BSD style: $(LICENSE) 4 version: Initial release: July 2008 5 author: Fawzi Mohamed 6 *******************************************************************************/ 7 module tango.math.random.engines.URandom; 8 version(darwin) { version=has_urandom; } 9 version(linux) { version=has_urandom; } 10 version(solaris){ version=has_urandom; } 11 12 version(has_urandom) { 13 private import Integer = tango.text.convert.Integer; 14 import tango.core.sync.Mutex: Mutex; 15 import tango.io.device.File; // use stdc read/write? 16 17 /// basic source that takes data from system random device 18 /// This is an engine, do not use directly, use RandomG!(Urandom) 19 /// should use stdc rad/write? 20 struct URandom{ 21 static __gshared File.Style readStyle; 22 static __gshared Mutex lock; 23 shared static this(){ 24 readStyle.access=File.Access.Read; 25 readStyle.open =File.Open.Exists; 26 readStyle.share =File.Share.Read; 27 readStyle.cache =File.Cache.None; 28 29 lock=new Mutex(); 30 } 31 enum int canCheckpoint=false; 32 enum int canSeed=false; 33 34 void skip(uint n){ } 35 ubyte nextB(){ 36 union ToVoidA{ 37 ubyte i; 38 void[1] a; 39 } 40 ToVoidA el; 41 synchronized(lock){ 42 auto fn = new File("/dev/urandom", readStyle); 43 if(fn.read(el.a)!=el.a.length){ 44 throw new Exception("could not write the requested bytes from urandom"); 45 } 46 fn.close(); 47 } 48 return el.i; 49 } 50 uint next(){ 51 union ToVoidA{ 52 uint i; 53 void[4] a; 54 } 55 ToVoidA el; 56 synchronized(lock){ 57 auto fn = new File("/dev/urandom", readStyle); 58 if(fn.read(el.a)!=el.a.length){ 59 throw new Exception("could not write the requested bytes from urandom"); 60 } 61 fn.close(); 62 } 63 return el.i; 64 } 65 ulong nextL(){ 66 union ToVoidA{ 67 ulong l; 68 void[8] a; 69 } 70 ToVoidA el; 71 synchronized(lock){ 72 auto fn = new File("/dev/urandom", readStyle); 73 if(fn.read(el.a)!=el.a.length){ 74 throw new Exception("could not write the requested bytes from urandom"); 75 } 76 fn.close(); 77 } 78 return el.l; 79 } 80 /// does nothing 81 void seed(scope uint delegate() r) { } 82 /// writes the current status in a string 83 immutable(char)[] toString(){ 84 return "URandom"; 85 } 86 /// reads the current status from a string (that should have been trimmed) 87 /// returns the number of chars read 88 size_t fromString(const(char[]) s){ 89 const(char)[] r="URandom"; 90 assert(s[0.. r.length]==r,"unxepected string instad of URandom:"~s); 91 return r.length; 92 } 93 } 94 }