0001"""
0002Create random secrets.
0003"""
0004
0005import os
0006import random
0007
0008def random_bytes(length):
0009    """
0010    Return a string of the given length.  Uses ``os.urandom`` if it
0011    can, or just pseudo-random numbers otherwise.
0012    """
0013    try:
0014        return os.urandom(length)
0015    except NotImplementedError:
0016        return ''.join([
0017            chr(random.randrange(256)) for i in xrange(length)])
0018
0019def secret_string(length=25):
0020    """
0021    Returns a random string of the given length.  The string
0022    is a base64-encoded version of a set of random bytes, truncated
0023    to the given length (and without any newlines).
0024    """
0025    s = random_bytes(length).encode('base64')
0026    for badchar in '\n\r=':
0027        s = s.replace(badchar, '')
0028    # We're wasting some characters here.  But random characters are
0029    # cheap ;)
0030    return s[:length]