Unique compact codes in Python

I was recently working on the problem of generating a unique code for every customer call that happens on our CRM portal. Now, one obvious solution would have been to use the epoch timestamp. But the issue was that this would have been 10-digits long. But a product constraint restricted the length of this code to 6 digits.

I found a very elegant solution on StackOverflow that addresses this issue. The idea was the since the code had to be alphanumeric, I need not restrict myself to base 10. Hexadecimal numbers use 16 digits (0 to 9, and A to F). Therefore, the number 100 takes 3 digits in the decimal system, and it takes only two digits (0x64) in the hexadecimal system. We can extend this idea to more digits. We have 10 numerical digits, and 26 letters (52 if you allow for case sensitivity). Therefore, I could express the 10-digit epoch timestamp in 6 digits or less in base 36.

This concept can be further extended. If you don’t need humans to process the code, you can even include the punctuation symbols (32 in number). If humans are processing the code, you may want to avoid this, as it becomes user-unfriendly. But otherwise, you can have potentially (10 numbers + 26 lowercase letters + 26 uppercase letters + 32 punctuation symbols) = 94 digits. Thus numbers from 0 to 93 can be expressed using a single digit, which is a massive upgrade from the decimal system (which only expresses numbers from 0 to 9 using a single digit).

import string
import time
digs = string.digits + string.ascii_lowercase + string.ascii_uppercase + string.punctuation


def unique_code(base):
    x = time.time()*1000
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)

unique_code(94)

The above function returns a 7-digit unique code every time you run it, with a time resolution of 1 ms, i.e., if you run the function twice, 1 ms apart, you will get a different code.

You can adjust the resolution to get shorter codes.

If you wish to restrict yourself to just lower case letters and numbers, you can set the base to 36. If you wish to include just letters and numbers, you can set the base to 62.

I hope you found this article helpful. You can find more Python-related posts here. Also, follow IoT Espresso on Twitter to get notified about every new post.

Leave a comment

Your email address will not be published. Required fields are marked *