Генерация случайной строки с заглавными буквами и цифрами - PullRequest
1187 голосов
/ 13 февраля 2010

Я хочу сгенерировать строку размером N.

Он должен состоять из цифр и заглавных букв английского алфавита, таких как:

  • 6U1S75
  • 4Z4UKK
  • U911K4

Как я могу достичь этого pythonic способом?

Ответы [ 27 ]

7 голосов
/ 08 января 2013

Этот метод немного быстрее и немного более раздражающий, чем метод random.choice (), опубликованный Игнасио.

Он использует преимущества псевдослучайных алгоритмов и использует битовые и смещениебыстрее, чем генерировать новое случайное число для каждого символа.

# must be length 32 -- 5 bits -- the question didn't specify using the full set
# of uppercase letters ;)
_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'

def generate_with_randbits(size=32):
    def chop(x):
        while x:
            yield x & 31
            x = x >> 5
    return  ''.join(_ALPHABET[x] for x in chop(random.getrandbits(size * 5))).ljust(size, 'A')

... создать генератор, который получает 5-битные числа за раз 0.31 до тех пор, пока не останется ни одного

...join () результаты генератора случайного числа с правильными битами

При использовании Timeit для 32-символьных строк время составило:

[('generate_with_random_choice', 28.92901611328125),
 ('generate_with_randbits', 20.0293550491333)]

... нодля 64-символьных строк рандбиты проигрывают;)

Я бы, вероятно, никогда не использовал бы этот подход в производственном коде, если бы мне действительно не нравились мои коллеги.

edit: обновлено в соответствии с вопросом (заглавными буквамии только цифры) и использовать побитовые операторы & и >> вместо% и //

5 голосов
/ 10 марта 2012

Я бы сделал это так:

import random
from string import digits, ascii_uppercase

legals = digits + ascii_uppercase

def rand_string(length, char_set=legals):

    output = ''
    for _ in range(length): output += random.choice(char_set)
    return output

Или просто:

def rand_string(length, char_set=legals):

    return ''.join( random.choice(char_set) for _ in range(length) )
4 голосов
/ 04 мая 2015
>>> import string 
>>> import random

следующая логика все еще генерирует случайную выборку из 6 символов

>>> print ''.join(random.sample((string.ascii_uppercase+string.digits),6))
JT7K3Q

Не нужно умножать на 6

>>> print ''.join(random.sample((string.ascii_uppercase+string.digits)*6,6))

TK82HK
4 голосов
/ 18 июня 2016

Используйте функцию random.choice () от Numpy

import numpy as np
import string        

if __name__ == '__main__':
    length = 16
    a = np.random.choice(list(string.ascii_uppercase + string.digits), length)                
    print(''.join(a))

Документация здесь http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html

3 голосов
/ 01 июля 2017

Это ответ на ответ Анурага Униьяла и то, над чем я работал сам.

import random
import string

oneFile = open('‪Numbers.txt', 'w')
userInput = 0
key_count = 0
value_count = 0
chars = string.ascii_uppercase + string.digits + string.punctuation

for userInput in range(int(input('How many 12 digit keys do you want?'))):
    while key_count <= userInput:
        key_count += 1
        number = random.randint(1, 999)
        key = number

        text = str(key) + ": " + str(''.join(random.sample(chars*6, 12)))
        oneFile.write(text + "\n")
oneFile.close()
3 голосов
/ 22 апреля 2016

(1) Это даст вам все заглавные буквы и цифры:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_uppercase))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey 

(2) Если позже вы захотите включить строчные буквы в свой ключ, то это также будет работать:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_letters))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey  
3 голосов
/ 02 февраля 2015

Для тех из вас, кто любит функциональный питон:

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))))

Он генерирует неопределенный [бесконечный] итератор из соединенных случайных последовательностей, сначала генерируя неопределенную последовательность случайно выбранных символов из пула-получателя,затем разбивая эту последовательность на части длины, которые затем соединяются, она должна работать с любой последовательностью, поддерживающей getitem, по умолчанию она просто генерирует случайную последовательность буквенно-цифровых букв, хотя вы можете легко изменить ее для генерации других вещей:

например, для генерации случайных наборов цифр:

>>> 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)

, если вы не хотите использовать следующее поколение, вы можете просто сделать его вызываемым:

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

, если вы хотитегенерируйте последовательность на лету, просто установите соединение с идентификатором.

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

Как уже упоминали другие, если вам нужна дополнительная безопасность, установите соответствующую функцию выбора:

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

селектор по умолчанию -choice, который может выбрать один и тот же символ несколько раз для каждого чанка, если вместо этого вы хотитеодин и тот же элемент выбирается не более одного раза для каждого чанка, затем возможное использование:

>>> 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]

мы используем sample в качестве нашего селектора, чтобы сделать полный выбор, так что чанки фактически имеют длину 1 и присоединяютсямы просто вызываем next, который выбирает следующий полностью сгенерированный кусок, при условии, что этот пример кажется немного громоздким, и это ...

2 голосов
/ 22 августа 2018
import random
q=2
o=1
list  =[r'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','s','0','1','2','3','4','5','6','7','8','9','0']
while(q>o):
    print("")

    for i in range(1,128):
        x=random.choice(list)
        print(x,end="")

Здесь длина строки может быть изменена для цикла, т.е. для i в диапазоне (1, длина) Это простой алгоритм, который легко понять. он использует список, так что вы можете отказаться от символов, которые вам не нужны.

2 голосов
/ 30 января 2014
>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be?  '))
How long do you want the string to be?  10
>>> for k in range(1, num+1):
...    str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'

Функция random.choice выбирает случайную запись в списке.Вы также создаете список, чтобы добавить символ в оператор for.В конце str [[t], 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], но str = "".join(str) позаботится об этом, оставив вас с 'tm2JUQ04CK'.

Надеюсь, это поможет!

2 голосов
/ 11 мая 2016
import string
from random import *
characters = string.ascii_letters + string.punctuation  + string.digits
password =  "".join(choice(characters) for x in range(randint(8, 16)))
print password
...