From: <le...@us...> - 2008-09-08 17:48:31
|
Revision: 5303 http://jython.svn.sourceforge.net/jython/?rev=5303&view=rev Author: leosoto Date: 2008-09-08 17:48:28 +0000 (Mon, 08 Sep 2008) Log Message: ----------- SystemRandom implementation taken from CPython. It depends on urandom(), which seems supported now through jna-posix Modified Paths: -------------- trunk/jython/Lib/random.py Modified: trunk/jython/Lib/random.py =================================================================== --- trunk/jython/Lib/random.py 2008-09-08 14:41:41 UTC (rev 5302) +++ trunk/jython/Lib/random.py 2008-09-08 17:48:28 UTC (rev 5303) @@ -43,7 +43,10 @@ from math import log as _log, exp as _exp, pi as _pi, e as _e from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import floor as _floor +from os import urandom as _urandom +from binascii import hexlify as _hexlify + __all__ = ["Random","seed","random","uniform","randint","choice","sample", "randrange","shuffle","normalvariate","lognormvariate", "cunifvariate","expovariate","vonmisesvariate","gammavariate", @@ -55,6 +58,7 @@ LOG4 = _log(4.0) SG_MAGICCONST = 1.0 + _log(4.5) BPF = 53 # Number of bits in a float +RECIP_BPF = 2**-BPF # Translated by Guido van Rossum from C source provided by # Adrian Baddeley. Adapted by Raymond Hettinger for use with @@ -768,24 +772,37 @@ ## --------------- Operating System Random Source ------------------ class SystemRandom(Random): + """Alternate random number generator using sources provided + by the operating system (such as /dev/urandom on Unix or + CryptGenRandom on Windows). + + Not available on all systems (see os.urandom() for details). """ - XXX: throw NotImplementedError for any attemt to use this for now. - """ def random(self): - self._notimplemented() + """Get the next random number in the range [0.0, 1.0).""" + return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF def getrandbits(self, k): - self._notimplemented() + """getrandbits(k) -> x. Generates a long int with k random bits.""" + if k <= 0: + raise ValueError('number of bits must be greater than zero') + if k != int(k): + raise TypeError('number of bits should be an integer') + bytes = (k + 7) // 8 # bits / 8 and rounded up + x = long(_hexlify(_urandom(bytes)), 16) + return x >> (bytes * 8 - k) # trim excess bits def _stub(self, *args, **kwds): - self._notimplemented() + "Stub method. Not used for a system random number generator." + return None + seed = jumpahead = _stub def _notimplemented(self, *args, **kwds): - raise NotImplementedError('SystemRandom not implemented on Jython.') + "Method should not be called for a system random number generator." + raise NotImplementedError('System entropy source does not have state.') getstate = setstate = _notimplemented - ## -------------------- test program -------------------- def _test_generator(n, funccall): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |