| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 | /******************************************************************************* copyright: Copyright (c) 2008. Fawzi Mohamed license: BSD style: $(LICENSE) version: Initial release: July 2008 author: Fawzi Mohamed *******************************************************************************/ module tango.math.random.engines.URandom; version(darwin) { version=has_urandom; } version(linux) { version=has_urandom; } version(solaris){ version=has_urandom; } version(has_urandom) { private import Integer = tango.text.convert.Integer; import tango.core.sync.Mutex: Mutex; import tango.io.device.File; // use stdc read/write? /// basic source that takes data from system random device /// This is an engine, do not use directly, use RandomG!(Urandom) /// should use stdc rad/write? struct URandom{ static __gshared File.Style readStyle; static __gshared Mutex lock; shared static this(){ readStyle.access=File.Access.Read; readStyle.open =File.Open.Exists; readStyle.share =File.Share.Read; readStyle.cache =File.Cache.None; lock=new Mutex(); } enum int canCheckpoint=false; enum int canSeed=false; void skip(uint n){ } ubyte nextB(){ union ToVoidA{ ubyte i; void[1] a; } ToVoidA el; synchronized(lock){ auto fn = new File("/dev/urandom", readStyle); if(fn.read(el.a)!=el.a.length){ throw new Exception("could not write the requested bytes from urandom"); } fn.close(); } return el.i; } uint next(){ union ToVoidA{ uint i; void[4] a; } ToVoidA el; synchronized(lock){ auto fn = new File("/dev/urandom", readStyle); if(fn.read(el.a)!=el.a.length){ throw new Exception("could not write the requested bytes from urandom"); } fn.close(); } return el.i; } ulong nextL(){ union ToVoidA{ ulong l; void[8] a; } ToVoidA el; synchronized(lock){ auto fn = new File("/dev/urandom", readStyle); if(fn.read(el.a)!=el.a.length){ throw new Exception("could not write the requested bytes from urandom"); } fn.close(); } return el.l; } /// does nothing void seed(scope uint delegate() r) { } /// writes the current status in a string immutable(char)[] toString(){ return "URandom"; } /// reads the current status from a string (that should have been trimmed) /// returns the number of chars read size_t fromString(const(char[]) s){ const(char)[] r="URandom"; assert(s[0.. r.length]==r,"unxepected string instad of URandom:"~s); return r.length; } } } |