Random string generation with upper case letters and digits

前端 未结 30 3744
逝去的感伤
逝去的感伤 2020-11-22 02:51

I want to generate a string of size N.

It should be made up of numbers and uppercase English letters such as:

  • 6U1S75
  • 4Z4UKK
  • U911K4
30条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-22 02:57

    For those of you who enjoy functional python:

    from itertools import imap, starmap, islice, repeat
    from functools import partial
    from string import letters, digits, join
    from random import choice
    
    join_chars = partial(join, sep='')
    identity = lambda o: o
    
    def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
        """ Generates an indefinite sequence of joined random symbols each of a specific length
        :param symbols: symbols to select,
            [defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
        :param length: the length of each sequence,
            [defaults to 6]
        :param join: method used to join selected symbol, 
            [defaults to ''.join generating a string.]
        :param select: method used to select a random element from the giving population. 
            [defaults to random.choice, which selects a single element randomly]
        :return: indefinite iterator generating random sequences of giving [:param length]
        >>> from tools import irand_seqs
        >>> strings = irand_seqs()
        >>> a = next(strings)
        >>> assert isinstance(a, (str, unicode))
        >>> assert len(a) == 6
        >>> assert next(strings) != next(strings)
        """
        return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))
    

    It generates an indefinite [infinite] iterator, of joined random sequences, by first generating an indefinite sequence of randomly selected symbol from the giving pool, then breaking this sequence into length parts which is then joined, it should work with any sequence that supports getitem, by default it simply generates a random sequence of alpha numeric letters, though you can easily modify to generate other things:

    for example to generate random tuples of digits:

    >>> irand_tuples = irand_seqs(xrange(10), join=tuple)
    >>> next(irand_tuples)
    (0, 5, 5, 7, 2, 8)
    >>> next(irand_tuples)
    (3, 2, 2, 0, 3, 1)
    

    if you don't want to use next for generation you can simply make it callable:

    >>> irand_tuples = irand_seqs(xrange(10), join=tuple)
    >>> make_rand_tuples = partial(next, irand_tuples) 
    >>> make_rand_tuples()
    (1, 6, 2, 8, 1, 9)
    

    if you want to generate the sequence on the fly simply set join to identity.

    >>> irand_tuples = irand_seqs(xrange(10), join=identity)
    >>> selections = next(irand_tuples)
    >>> next(selections)
    8
    >>> list(selections)
    [6, 3, 8, 2, 2]
    

    As others have mentioned if you need more security then set the appropriate select function:

    >>> from random import SystemRandom
    >>> rand_strs = irand_seqs(select=SystemRandom().choice)
    'QsaDxQ'
    

    the default selector is choice which may select the same symbol multiple times for each chunk, if instead you'd want the same member selected at most once for each chunk then, one possible usage:

    >>> from random import sample
    >>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
    >>> next(irand_samples)
    [0, 9, 2, 3, 1, 6]
    

    we use sample as our selector, to do the complete selection, so the chunks are actually length 1, and to join we simply call next which fetches the next completely generated chunk, granted this example seems a bit cumbersome and it is ...

提交回复
热议问题