Skip to content

Instantly share code, notes, and snippets.

@pior
Last active August 29, 2015 14:17
Show Gist options
  • Save pior/5cd139d4c3b9ee327343 to your computer and use it in GitHub Desktop.
Save pior/5cd139d4c3b9ee327343 to your computer and use it in GitHub Desktop.
Random Key in python
import base64
import random
from binascii import unhexlify, b2a_base64
def long_to_bytes (val):
"""
Use :ref:`string formatting` and :func:`~binascii.unhexlify` to
convert ``val``, a :func:`long`, to a byte :func:`str`.
:param long val: The value to pack
Using :ref:`string formatting` lets us use Python's C innards.
"""
# one (1) hex digit per four (4) bits
width = val.bit_length()
# unhexlify wants an even multiple of eight (8) bits, but we don't
# want more digits than we need (hence the ternary-ish 'or')
width += 8 - ((width % 8) or 8)
# format width specifier: four (4) bits per hex digit
fmt = '%%0%dx' % (width // 4)
# prepend zero (0) to the width, to zero-pad the output
return unhexlify(fmt % val)
def generate_uid(bitlength=120):
rand = random.getrandbits(bitlength)
return base64.urlsafe_b64encode(long_to_bytes(rand))
def faster_generate_uid(bitlength=120):
rand = random.getrandbits(bitlength)
s = b2a_base64(long_to_bytes(rand))
return s.replace('+', '-').replace('/', '_')
"""
Entropy provided by a Base62 string:
2 chars: 11 bits
4 chars: 23 bits
6 chars: 35 bits
8 chars: 47 bits
10 chars: 59 bits
12 chars: 71 bits
14 chars: 83 bits
16 chars: 95 bits
18 chars: 107 bits
20 chars: 119 bits
22 chars: 130 bits
24 chars: 142 bits
26 chars: 154 bits
28 chars: 166 bits
30 chars: 178 bits
32 chars: 190 bits
34 chars: 202 bits
36 chars: 214 bits
38 chars: 226 bits
40 chars: 238 bits
42 chars: 250 bits
44 chars: 261 bits
46 chars: 273 bits
48 chars: 285 bits
50 chars: 297 bits
52 chars: 309 bits
54 chars: 321 bits
56 chars: 333 bits
58 chars: 345 bits
60 chars: 357 bits
62 chars: 369 bits
64 chars: 381 bits
"""
base62_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def make_base62_uid(length=16):
return ''.join([base62_chars[int(random.random() * 62)] for _ in range(length)])
def make_base62_uid_and_integer(length=10):
"""A length of 10 would produce 8 bytes integers"""
seq =[int(random.random() * 62) for _ in range(length)]
value = 0
for e in seq:
value = value * 62 + e
return (''.join([base62_chars[e] for e in seq]), value)
@pior
Copy link
Author

pior commented Mar 26, 2015

In [79]: %timeit faster_generate_uid()
100000 loops, best of 3: 11.7 µs per loop

@pior
Copy link
Author

pior commented Mar 26, 2015

In [81]: %timeit '%x' % random.getrandbits(120)
1000000 loops, best of 3: 1.79 µs per loop

@pior
Copy link
Author

pior commented Mar 26, 2015

chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
length = 62

def uid():
    return ''.join([chars[int(random.random() * length)] for _ in range(16)])
In [65]: uid()
Out[65]: 'hZJAmloh6JMbcwKm'

In [66]: %timeit uid()
100000 loops, best of 3: 3.48 µs per loop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment