|
1 | 1 | """Generate cryptographically strong pseudo-random numbers suitable for |
2 | 2 | managing secrets such as account authentication, tokens, and similar. |
3 | | -See PEP 506 for more information. |
4 | 3 |
|
| 4 | +See PEP 506 for more information. |
5 | 5 | https://www.python.org/dev/peps/pep-0506/ |
6 | 6 |
|
7 | | -
|
8 | | -Random numbers |
9 | | -============== |
10 | | -
|
11 | | -The ``secrets`` module provides the following pseudo-random functions, based |
12 | | -on SystemRandom, which in turn uses the most secure source of randomness your |
13 | | -operating system provides. |
14 | | -
|
15 | | -
|
16 | | - choice(sequence) |
17 | | - Choose a random element from a non-empty sequence. |
18 | | -
|
19 | | - randbelow(n) |
20 | | - Return a random int in the range [0, n). |
21 | | -
|
22 | | - randbits(k) |
23 | | - Generates an int with k random bits. |
24 | | -
|
25 | | - SystemRandom |
26 | | - Class for generating random numbers using sources provided by |
27 | | - the operating system. See the ``random`` module for documentation. |
28 | | -
|
29 | | -
|
30 | | -Token functions |
31 | | -=============== |
32 | | -
|
33 | | -The ``secrets`` module provides a number of functions for generating secure |
34 | | -tokens, suitable for applications such as password resets, hard-to-guess |
35 | | -URLs, and similar. All the ``token_*`` functions take an optional single |
36 | | -argument specifying the number of bytes of randomness to use. If that is |
37 | | -not given, or is ``None``, a reasonable default is used. That default is |
38 | | -subject to change at any time, including during maintenance releases. |
39 | | -
|
40 | | -
|
41 | | - token_bytes(nbytes=None) |
42 | | - Return a random byte-string containing ``nbytes`` number of bytes. |
43 | | -
|
44 | | - >>> secrets.token_bytes(16) #doctest:+SKIP |
45 | | - b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b' |
46 | | -
|
47 | | -
|
48 | | - token_hex(nbytes=None) |
49 | | - Return a random text-string, in hexadecimal. The string has ``nbytes`` |
50 | | - random bytes, each byte converted to two hex digits. |
51 | | -
|
52 | | - >>> secrets.token_hex(16) #doctest:+SKIP |
53 | | - 'f9bf78b9a18ce6d46a0cd2b0b86df9da' |
54 | | -
|
55 | | - token_urlsafe(nbytes=None) |
56 | | - Return a random URL-safe text-string, containing ``nbytes`` random |
57 | | - bytes. On average, each byte results in approximately 1.3 characters |
58 | | - in the final result. |
59 | | -
|
60 | | - >>> secrets.token_urlsafe(16) #doctest:+SKIP |
61 | | - 'Drmhze6EPcv0fN_81Bj-nA' |
62 | | -
|
63 | | -
|
64 | | -(The examples above assume Python 3. In Python 2, byte-strings will display |
65 | | -using regular quotes ``''`` with no prefix, and text-strings will have a |
66 | | -``u`` prefix.) |
67 | | -
|
68 | | -
|
69 | | -Other functions |
70 | | -=============== |
71 | | -
|
72 | | - compare_digest(a, b) |
73 | | - Return True if strings a and b are equal, otherwise False. |
74 | | - Performs the equality comparison in such a way as to reduce the |
75 | | - risk of timing attacks. |
76 | | -
|
77 | | - See http://codahale.com/a-lesson-in-timing-attacks/ for a |
78 | | - discussion on how timing attacks against ``==`` can reveal |
79 | | - secrets from your application. |
80 | | -
|
81 | | -
|
82 | 7 | """ |
83 | 8 |
|
84 | 9 | __all__ = ['choice', 'randbelow', 'randbits', 'SystemRandom', |
|
100 | 25 | choice = _sysrand.choice |
101 | 26 |
|
102 | 27 | def randbelow(exclusive_upper_bound): |
| 28 | + """Return a random int in the range [0, n).""" |
103 | 29 | return _sysrand._randbelow(exclusive_upper_bound) |
104 | 30 |
|
105 | 31 | DEFAULT_ENTROPY = 32 # number of bytes to return by default |
106 | 32 |
|
107 | 33 | def token_bytes(nbytes=None): |
| 34 | + """Return a random byte string containing *nbytes* bytes. |
| 35 | +
|
| 36 | + If *nbytes* is ``None`` or not supplied, a reasonable |
| 37 | + default is used. |
| 38 | +
|
| 39 | + >>> token_bytes(16) #doctest:+SKIP |
| 40 | + b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b' |
| 41 | +
|
| 42 | + """ |
108 | 43 | if nbytes is None: |
109 | 44 | nbytes = DEFAULT_ENTROPY |
110 | 45 | return os.urandom(nbytes) |
111 | 46 |
|
112 | 47 | def token_hex(nbytes=None): |
| 48 | + """Return a random text string, in hexadecimal. |
| 49 | +
|
| 50 | + The string has *nbytes* random bytes, each byte converted to two |
| 51 | + hex digits. If *nbytes* is ``None`` or not supplied, a reasonable |
| 52 | + default is used. |
| 53 | +
|
| 54 | + >>> token_hex(16) #doctest:+SKIP |
| 55 | + 'f9bf78b9a18ce6d46a0cd2b0b86df9da' |
| 56 | +
|
| 57 | + """ |
113 | 58 | return binascii.hexlify(token_bytes(nbytes)).decode('ascii') |
114 | 59 |
|
115 | 60 | def token_urlsafe(nbytes=None): |
| 61 | + """Return a random URL-safe text string, in Base64 encoding. |
| 62 | +
|
| 63 | + The string has *nbytes* random bytes. If *nbytes* is ``None`` |
| 64 | + or not supplied, a reasonable default is used. |
| 65 | +
|
| 66 | + >>> token_urlsafe(16) #doctest:+SKIP |
| 67 | + 'Drmhze6EPcv0fN_81Bj-nA' |
| 68 | +
|
| 69 | + """ |
116 | 70 | tok = token_bytes(nbytes) |
117 | 71 | return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii') |
0 commit comments