What's the best way to generate random strings of a specific length in Python?

后端 未结 6 970
感情败类
感情败类 2020-12-02 17:05

For a project, I need a method of creating thousands of random strings while keeping collisions low. I\'m looking for them to be only 12 characters long and uppercase only.

相关标签:
6条回答
  • 2020-12-02 17:31

    Could make a generator:

    from string import ascii_uppercase
    import random
    from itertools import islice
    
    def random_chars(size, chars=ascii_uppercase):
        selection = iter(lambda: random.choice(chars), object())
        while True:
            yield ''.join(islice(selection, size))
    
    random_gen = random_chars(12)
    print next(random_gen)
    # LEQIITOSJZOQ
    print next(random_gen)
    # PXUYJTOTHWPJ
    

    Then just pull from the generator when they're needed... Either using next(random_gen) when you need them, or use random_200 = list(islice(random_gen, 200)) for instance...

    0 讨论(0)
  • 2020-12-02 17:32

    This function generates random string of UPPERCASE letters with the specified length,

    eg: length = 6, will generate the following random sequence pattern

    YLNYVQ

        import random as r
    
        def generate_random_string(length):
            random_string = ''
            random_str_seq = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            for i in range(0,length):
                if i % length == 0 and i != 0:
                    random_string += '-'
                random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
            return random_string
    
    0 讨论(0)
  • 2020-12-02 17:35

    For cryptographically strong pseudo-random bytes you might use the pyOpenSSL wrapper around OpenSSL.

    It provides the bytes function to gather a pseudo-random sequences of bytes.

    from OpenSSL import rand
    
    b = rand.bytes(7)
    

    BTW, 12 uppercase letters is a little bit more that 56 bits of entropy. You will only to have to read 7 bytes.

    0 讨论(0)
  • 2020-12-02 17:46
    #!/bin/python3
    import random
    import string
    def f(n: int) -> str:
            bytes(random.choices(string.ascii_uppercase.encode('ascii'),k=n)).decode('ascii')
    

    run faster for very big n. avoid str concatenate.

    0 讨论(0)
  • 2020-12-02 17:47

    CODE:

    from random import choice
    from string import ascii_uppercase
    
    print(''.join(choice(ascii_uppercase) for i in range(12)))
    

    OUTPUT:

    5 examples:

    QPUPZVVHUNSN
    EFJACZEBYQEB
    QBQJJEEOYTZY
    EOJUSUEAJEEK
    QWRWLIWDTDBD
    

    EDIT:

    If you need only digits, use the digits constant instead of the ascii_uppercase one from the string module.

    3 examples:

    229945986931
    867348810313
    618228923380
    
    0 讨论(0)
  • 2020-12-02 17:47

    By Django, you can use get_random_string function in django.utils.crypto module.

    get_random_string(length=12,
        allowed_chars=u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
        Returns a securely generated random string.
    
        The default length of 12 with the a-z, A-Z, 0-9 character set returns
        a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
    

    Example:

    get_random_string()
    u'ngccjtxvvmr9'
    
    get_random_string(4, allowed_chars='bqDE56')
    u'DDD6'
    

    But if you don't want to have Django, here is independent code of it:

    Code:

    import random
    import hashlib
    import time
    
    SECRET_KEY = 'PUT A RANDOM KEY WITH 50 CHARACTERS LENGTH HERE !!'
    
    try:
        random = random.SystemRandom()
        using_sysrandom = True
    except NotImplementedError:
        import warnings
        warnings.warn('A secure pseudo-random number generator is not available '
                      'on your system. Falling back to Mersenne Twister.')
        using_sysrandom = False
    
    
    def get_random_string(length=12,
                          allowed_chars='abcdefghijklmnopqrstuvwxyz'
                                        'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
        """
        Returns a securely generated random string.
    
        The default length of 12 with the a-z, A-Z, 0-9 character set returns
        a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
        """
        if not using_sysrandom:
            # This is ugly, and a hack, but it makes things better than
            # the alternative of predictability. This re-seeds the PRNG
            # using a value that is hard for an attacker to predict, every
            # time a random string is required. This may change the
            # properties of the chosen random sequence slightly, but this
            # is better than absolute predictability.
            random.seed(
                hashlib.sha256(
                    ("%s%s%s" % (
                        random.getstate(),
                        time.time(),
                        SECRET_KEY)).encode('utf-8')
                ).digest())
        return ''.join(random.choice(allowed_chars) for i in range(length))
    
    0 讨论(0)
提交回复
热议问题