Efficiently generate a 16-character, alphanumeric string

111,128

Solution 1

As none of the answers provide you with a random string consisting of characters 0-9, a-z, A-Z: Here is a working solution which will give you one of approx. 62^16 = 4.76724 e+28 keys:

import random, string
x = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(16))
print(x)

It is also very readable without knowing ASCII codes by heart.

There is an even shorter version since python 3.6.2:

import random, string
x = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(x)

Solution 2

You can use this:

>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'

There is no guarantee that the keys generated will be unique so you should be ready to retry with a new key in the case the original insert fails. Also, you might want to consider using a deterministic algorithm to generate a string from an auto-incremented id instead of using random values, as this will guarantee you uniqueness (but it will also give predictable keys).

Solution 3

Have a look at the uuid module (Python 2.5+).

A quick example:

>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'

Note that the OP asked for a 16-character alphanumeric string, but UUID4 strings are 32 characters long. You should not truncate this string, instead, use the complete 32 characters.

Solution 4

In Python 3.6, released in December 2016, the secrets module was introduced.

You can now generate a random token this way :

import secrets

secrets.token_hex(16)

From the Python docs :

The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.

In particularly, secrets should be used in preference to the default pseudo-random number generator in the random module, which is designed for modelling and simulation, not security or cryptography.

https://docs.python.org/3/library/secrets.html

Solution 5

For random numbers a good source is os.urandom:

 >> import os
 >> import hashlib
 >> random_data = os.urandom(128)
 >> hashlib.md5(random_data).hexdigest()[:16]
Share:
111,128
ensnare
Author by

ensnare

Updated on October 01, 2021

Comments

  • ensnare
    ensnare over 2 years

    I'm looking for a very quick way to generate an alphanumeric unique id for a primary key in a table.

    Would something like this work?

    def genKey():
        hash = hashlib.md5(RANDOM_NUMBER).digest().encode("base64")
        alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", hash)
        return alnum_hash[:16]
    

    What would be a good way to generate random numbers? If I base it on microtime, I have to account for the possibility of several calls of genKey() at the same time from different instances.

    Or is there a better way to do all this?