Marco Fernandes
Marco Fernandes

Reputation: 336

How do I generate a random alphanumeric string in Python?

I have been migrating javascript code to python and I am stuck trying to get a python version of Math.random().toString(36)

I'm not sure how to do this since Math.random() returns a float, in python I have not been able to figure out how to convert a float to base36. From what I understand it's only int but then how does javascript do it?

for getting a random float in python I just use the following:

import random

random.uniform(0, 1)

and for encoding I used the wiki example:

#from wiki
def base36encode(integer: int) -> str:
    ...

-EDIT: original js code:

function randomString(length) {
    return Array(length + 1).join((Math.random().toString(36) + '00000000000000000').slice(2, 18)).slice(0, length);
}

Upvotes: 0

Views: 2273

Answers (3)

Jason R. Coombs
Jason R. Coombs

Reputation: 42694

The javascript code you've presented is doing something clever. Instead of generating a new random number for each character, it's using the full entropy of the random float to generate a number of characters and taking advantage of the built-in property of "toString" to generate characters in base 36.

> Math.random().toString(36)
'0.w52uct13wyk'
> Math.random().toString(36)
'0.b1lvdlnydht'

The routine then pads that string with zeros and slices the requested length out of it. Note it won't produce string longer than 16 characters and from my observation won't produce any randomness beyond the 11th character. Depending on the cost of your random number generator, it might be more efficient to generate more characters from a single random number.

Best I can tell, Python doesn't provide any built-in mechanism to convert a float or integer to a string in an arbitrary base, although I did find a way to convert to base32 using struct and base64.b32decode. This answer, however, indicates that it's possible to do something similar to the javascript example using the basencode package.

>>> import basencode
>>> import random
>>> basencode.Number(random.random()).repr_in_base(36)
'0.02wute64uix8fr5umlypeg0c1ajb32xnc8rc6fvv5njesya2mesaxgn8wtchw6grnk5zgmlsm2zojr3fnuqmy3lluj26zgv6lxad'

Putting that together like the javascript code, you'd get something like:

import basencode
import random

def random_string(length):
    return basencode.Number(random.random()).repr_in_base(36)[2:][:length]

This routine as written would only return the number of characters that repr_in_base supplies, however, so to support an arbitrary length, you'd need to chain some results:

import basencode
import random

def random_string(length):
    if length < 1:
        return ''
    result = basencode.Number(random.random()).repr_in_base(36)[2:][:length]
    return result + random_string(length - len(result))
>>> random_string(500)
'yodvlesezo3n9cw52mq76gewlidsqil9e5t0prsutitr67vwbhtcobjrhijpap30u9ktfde2x15vnkuphuhx47by25zrn4ydz19aj0k31jf5jqn6v1fgmnzf0wfoqiltsps1ga96uy8cl40m8on2ag8igvp26q7f3qo0bt5rs7nh3ga1atymcoql0rsy3tjlyv3lualmvtt084quw7pxqwmbix20ka1yjrknjr1l939fjufkobz8wmq7mp5f3ku3lef58xmrvlfbmudbz348scvbxwkjoyibqkug3be1zfkg948cre7urtoahk3ll0iv98vvl8yypadd9jsnmdczurokk914qwubxmn7uqug60tn2sufj1vt2ju1e8cas3m19peib97f5gtnqgiqp0pddilrn00okyltsilflqp0t2r50l1ke7l57rb2fuaxqcwapv5cbdp19d5l0av0rzmqtl0g5dhg5b4uny8a7w6xp99sxr1iyo8b'

It might be interesting to see how this approach compares when benchmarked against the single-character generator, but I'll leave that as an exercise to the reader.

Upvotes: 0

danetgenius
danetgenius

Reputation: 1

import random
import string

Define the length of the string

length = 10

Define the pool of characters to choose from

pool = string.ascii_letters + string.digits

Generate the random string

random_string = ''.join(random.choice(pool) for i in range(length))

print(random_string)

Upvotes: 0

Azamat Galimzhanov
Azamat Galimzhanov

Reputation: 638

Going from comments. In JS using base36 is done to generate random alphanumeric characters. That is 26 from the alphabet + 10 digits.

In python you can generate a random alphanumeric string of a given length like this:

import random, string

def random_string(length):
    return ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(length))

Upvotes: 1

Related Questions