| Index: third_party/google-endpoints/Crypto/Random/random.py
|
| diff --git a/third_party/google-endpoints/Crypto/Random/random.py b/third_party/google-endpoints/Crypto/Random/random.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bef02e6511a2d3bd9197ed47c3bc345acac62f99
|
| --- /dev/null
|
| +++ b/third_party/google-endpoints/Crypto/Random/random.py
|
| @@ -0,0 +1,142 @@
|
| +# -*- coding: utf-8 -*-
|
| +#
|
| +# Random/random.py : Strong alternative for the standard 'random' module
|
| +#
|
| +# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
| +#
|
| +# ===================================================================
|
| +# The contents of this file are dedicated to the public domain. To
|
| +# the extent that dedication to the public domain is not available,
|
| +# everyone is granted a worldwide, perpetual, royalty-free,
|
| +# non-exclusive license to exercise all rights associated with the
|
| +# contents of this file for any purpose whatsoever.
|
| +# No rights are reserved.
|
| +#
|
| +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
| +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
| +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
| +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| +# SOFTWARE.
|
| +# ===================================================================
|
| +
|
| +"""A cryptographically strong version of Python's standard "random" module."""
|
| +
|
| +__revision__ = "$Id$"
|
| +__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample']
|
| +
|
| +from Crypto import Random
|
| +import sys
|
| +if sys.version_info[0] == 2 and sys.version_info[1] == 1:
|
| + from Crypto.Util.py21compat import *
|
| +
|
| +class StrongRandom(object):
|
| + def __init__(self, rng=None, randfunc=None):
|
| + if randfunc is None and rng is None:
|
| + self._randfunc = None
|
| + elif randfunc is not None and rng is None:
|
| + self._randfunc = randfunc
|
| + elif randfunc is None and rng is not None:
|
| + self._randfunc = rng.read
|
| + else:
|
| + raise ValueError("Cannot specify both 'rng' and 'randfunc'")
|
| +
|
| + def getrandbits(self, k):
|
| + """Return a python long integer with k random bits."""
|
| + if self._randfunc is None:
|
| + self._randfunc = Random.new().read
|
| + mask = (1L << k) - 1
|
| + return mask & bytes_to_long(self._randfunc(ceil_div(k, 8)))
|
| +
|
| + def randrange(self, *args):
|
| + """randrange([start,] stop[, step]):
|
| + Return a randomly-selected element from range(start, stop, step)."""
|
| + if len(args) == 3:
|
| + (start, stop, step) = args
|
| + elif len(args) == 2:
|
| + (start, stop) = args
|
| + step = 1
|
| + elif len(args) == 1:
|
| + (stop,) = args
|
| + start = 0
|
| + step = 1
|
| + else:
|
| + raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args),))
|
| + if (not isinstance(start, (int, long))
|
| + or not isinstance(stop, (int, long))
|
| + or not isinstance(step, (int, long))):
|
| + raise TypeError("randrange requires integer arguments")
|
| + if step == 0:
|
| + raise ValueError("randrange step argument must not be zero")
|
| +
|
| + num_choices = ceil_div(stop - start, step)
|
| + if num_choices < 0:
|
| + num_choices = 0
|
| + if num_choices < 1:
|
| + raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step))
|
| +
|
| + # Pick a random number in the range of possible numbers
|
| + r = num_choices
|
| + while r >= num_choices:
|
| + r = self.getrandbits(size(num_choices))
|
| +
|
| + return start + (step * r)
|
| +
|
| + def randint(self, a, b):
|
| + """Return a random integer N such that a <= N <= b."""
|
| + if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
|
| + raise TypeError("randint requires integer arguments")
|
| + N = self.randrange(a, b+1)
|
| + assert a <= N <= b
|
| + return N
|
| +
|
| + def choice(self, seq):
|
| + """Return a random element from a (non-empty) sequence.
|
| +
|
| + If the seqence is empty, raises IndexError.
|
| + """
|
| + if len(seq) == 0:
|
| + raise IndexError("empty sequence")
|
| + return seq[self.randrange(len(seq))]
|
| +
|
| + def shuffle(self, x):
|
| + """Shuffle the sequence in place."""
|
| + # Make a (copy) of the list of objects we want to shuffle
|
| + items = list(x)
|
| +
|
| + # Choose a random item (without replacement) until all the items have been
|
| + # chosen.
|
| + for i in xrange(len(x)):
|
| + x[i] = items.pop(self.randrange(len(items)))
|
| +
|
| + def sample(self, population, k):
|
| + """Return a k-length list of unique elements chosen from the population sequence."""
|
| +
|
| + num_choices = len(population)
|
| + if k > num_choices:
|
| + raise ValueError("sample larger than population")
|
| +
|
| + retval = []
|
| + selected = {} # we emulate a set using a dict here
|
| + for i in xrange(k):
|
| + r = None
|
| + while r is None or selected.has_key(r):
|
| + r = self.randrange(num_choices)
|
| + retval.append(population[r])
|
| + selected[r] = 1
|
| + return retval
|
| +
|
| +_r = StrongRandom()
|
| +getrandbits = _r.getrandbits
|
| +randrange = _r.randrange
|
| +randint = _r.randint
|
| +choice = _r.choice
|
| +shuffle = _r.shuffle
|
| +sample = _r.sample
|
| +
|
| +# These are at the bottom to avoid problems with recursive imports
|
| +from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes, size
|
| +
|
| +# vim:set ts=4 sw=4 sts=4 expandtab:
|
|
|