132

How do you create a random string in Python?

I need it to be number then character, repeating until the iteration is done.

This is what I created:

def random_id(length):
    number = '0123456789'
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    id = ''
    for i in range(0,length,2):
        id += random.choice(number)
        id += random.choice(alpha)
    return id
ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
RHicke
  • 3,494
  • 3
  • 23
  • 23

13 Answers13

269

Generating strings from (for example) lowercase characters:

import random, string

def randomword(length):
   letters = string.ascii_lowercase
   return ''.join(random.choice(letters) for i in range(length))

Results:

>>> randomword(10)
'vxnxikmhdc'
>>> randomword(10)
'ytqhdohksy'
sth
  • 222,467
  • 53
  • 283
  • 367
82

Since this question is fairly, uh, random, this may work for you:

import uuid
print(uuid.uuid4())
58fe9784-f60a-42bc-aa94-eb8f1a7e5c17
Jurakin
  • 832
  • 1
  • 5
  • 19
Brandon
  • 3,684
  • 1
  • 18
  • 25
43
import random
import string

s = string.lowercase+string.digits
print(''.join(random.sample(s, 10)))
# prints 'jw72qidagk'
Michael M.
  • 10,486
  • 9
  • 18
  • 34
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • Neat! I'm actually using this for a random password generator now! Thanks! – chandsie Apr 15 '11 at 00:45
  • 14
    random.sample will sample unique characters from s, ie characters in the password will never repeat. This is considerably less secure than the using random.choice as in the accepted answer. – Nick Zalutskiy Jan 20 '12 at 05:26
  • 4
    @NickZalutskiy: `random.choice` is not secure either. Use `random.SystemRandom().choice()` or [use `os.urandom()` directly](http://stackoverflow.com/a/16310739/4279). – jfs Jun 08 '16 at 11:25
  • 1
    WARNING! take note of two comments above. random.sample returns unique samples. characters are not repeated. so returned string is less random. For larger strings error: 'ValueError: sample larger than population'. – gaoithe Apr 03 '17 at 11:35
  • Also a consequence of the above comments - the sample cannot be larger than the selected chars ("population"), so even if you don't need this for any security-related task, you cannot make long strings with `random.sample`. Fortunately, using a generator with `rand.choice` is just as simple. – Czechnology May 23 '18 at 17:25
  • simple but misleading solution. As stated above, sample will not do wat people expect in most cases. Better to use `random.choices` for that matter. – Romain Vincent Aug 23 '18 at 08:42
  • 2
    In Python 3, `lowercase` should be replaced with `ascii_lowercase` – Nicolai Lissau Dec 10 '18 at 21:23
19

Answer to the original question:

os.urandom(n)

Quote from: http://docs.python.org/2/library/os.html

Return a string of n random bytes suitable for cryptographic use.

This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation. On a UNIX-like system this will query /dev/urandom, and on Windows it will use CryptGenRandom. If a randomness source is not found, NotImplementedError will be raised.

For an easy-to-use interface to the random number generator provided by your platform, please see random.SystemRandom.

Tom
  • 3,115
  • 6
  • 33
  • 38
6

You can build random ascii characters like:

import random
print chr(random.randint(0,128))

And then build up a longer string like:

len = 50
print ''.join( [chr(random.randint(0,128)) for i in xrange(0,len)] )
Community
  • 1
  • 1
Ross Rogers
  • 23,523
  • 27
  • 108
  • 164
6

Sometimes, I've wanted random strings that are semi-pronounceable, semi-memorable.

import random

def randomWord(length=5):
    consonants = "bcdfghjklmnpqrstvwxyz"
    vowels = "aeiou"

    return "".join(random.choice((consonants, vowels)[i%2]) for i in range(length))

Then,

>>> randomWord()
nibit
>>> randomWord()
piber
>>> randomWord(10)
rubirikiro

To avoid 4-letter words, don't set length to 4.

Jim

Jim
  • 474
  • 5
  • 17
6

In python3.6+ you can use the secrets module:

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.

In testing generation of 768bit security tokens I found:

  • random.choices() - 0.000246 secs
  • secrets.choice() - 0.003529 secs

The secrets modules is slower but outside of testing it is what you should be using for cryptographic purposes:

import string, secrets

def random_string(size):        
        letters = string.ascii_lowercase+string.ascii_uppercase+string.digits            
        return ''.join(secrets.choice(letters) for i in range(size))

print(random_string(768))
Stuart Cardall
  • 2,099
  • 24
  • 18
  • 1
    Thank you for this answer :). I'd like to add that `secrets.token_hex(n)` also returns a random string, not with uppercase characters, but still, a random string of characters and numbers. – ivanleoncz Mar 17 '22 at 00:24
5

You haven't really said much about what sort of random string you need. But in any case, you should look into the random module.

A very simple solution is pasted below.

import random

def randstring(length=10):
    valid_letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return ''.join((random.choice(valid_letters) for i in xrange(length)))

print randstring()
print randstring(20)
MAK
  • 26,140
  • 11
  • 55
  • 86
3
random_name = lambda length: ''.join(random.sample(string.letters, length))

length must be <= len(string.letters) = 53. result example

   >>> [random_name(x) for x in range(1,20)]
['V', 'Rq', 'YtL', 'AmUF', 'loFdS', 'eNpRFy', 'iWFGtDz', 'ZTNgCvLA', 'fjUDXJvMP', 'EBrPcYKUvZ', 'GmxPKCnbfih', 'nSiNmCRktdWZ', 'VWKSsGwlBeXUr', 'i
stIFGTUlZqnav', 'bqfwgBhyTJMUEzF', 'VLXlPiQnhptZyoHq', 'BXWATvwLCUcVesFfk', 'jLngHmTBtoOSsQlezV', 'JOUhklIwDBMFzrTCPub']
>>> 

Enjoy. ;)

Spouk
  • 691
  • 7
  • 18
2

Install this package:

pip3 install py_essentials

And use this code:

from py_essentials import simpleRandom as sr
print(sr.randomString(4))

More informations about the method other parameters are available here.

1cedsoda
  • 623
  • 4
  • 16
1
import random 
import string

def get_random_string(size):
    chars = string.ascii_lowercase+string.ascii_uppercase+string.digits
    ''.join(random.choice(chars) for _ in range(size))

print(get_random_string(20)

output : FfxjmkyyLG5HvLeRudDS

0

This function generates random string consisting of upper,lowercase letters, digits, pass the length seperator, no_of_blocks to specify your string format

eg: len_sep = 4, no_of_blocks = 4 will generate the following pattern,

F4nQ-Vh5z-JKEC-WhuS

Where, length seperator will add "-" after 4 characters

XXXX-

no of blocks will generate the following patten of characters as string

XXXX - XXXX - XXXX - XXXX

if a single random string is needed, just keep the no_of_blocks variable to be equal to 1 and len_sep to specify the length of the random string.

eg: len_sep = 10, no_of_blocks = 1, will generate the following pattern ie. random string of length 10,

F01xgCdoDU

import random as r

def generate_random_string(len_sep, no_of_blocks):
    random_string = ''
    random_str_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    for i in range(0,len_sep*no_of_blocks):
        if i % len_sep == 0 and i != 0:
            random_string += '-'
        random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
    return random_string
Manoj Selvin
  • 2,247
  • 24
  • 20
0

A better implementation:

def generate_random_letters(length: int, uppercase: bool = True, lowercase: bool = True, numbers: bool = True):
choices = ''
if uppercase:
    choices += string.ascii_uppercase

if lowercase:
    choices += string.ascii_lowercase

if numbers:
    choices += string.digits

return ''.join(random.choice(choices) for _ in range(length))
zkscpqm
  • 69
  • 1
  • 5