Генерация случайных строк с заглавными буквами и цифрами
Как мне сгенерировать строку размера N, состоящую из цифр и заглавных английских букв, таких как:
- 6U1S75
- 4Z4UKK
- U911K4
Переведено автоматически
Ответ 1
Ответ в одну строку:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
или даже короче, начиная с Python 3.6 с использованием random.choices()
:
''.join(random.choices(string.ascii_uppercase + string.digits, k=N))
Криптографически более безопасная версия: смотрите этот пост
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
Подробнее, с чистой функцией для дальнейшего использования:
>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
... return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'
Как это работает?
Мы импортируем string
, модуль, который содержит последовательности обычных символов ASCII, и random
, модуль, который занимается генерацией случайных строк.
string.ascii_uppercase + string.digits
просто объединяет список символов, представляющих символы ASCII в верхнем регистре и цифры:
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
Затем мы используем представление списка для создания списка из 'n' элементов:
>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']
В приведенном выше примере мы используем [
для создания списка, но не в id_generator
функции, поэтому Python не создает список в памяти, а генерирует элементы на лету, один за другим (подробнее об этом здесь).
Вместо запроса создать строку, умноженную на 'n' elem
, мы попросим Python создать 'n' раз случайный символ, выбранный из последовательности символов:
>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'
Таким образом, random.choice(chars) for _ in range(size)
на самом деле создается последовательность size
символов. Символы, выбранные случайным образом из chars
:
>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']
Затем мы просто соединяем их пустой строкой, чтобы последовательность стала строкой:
>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'
Ответ 2
Этот вопрос Stack Overflow является текущим лучшим результатом Google для "Python со случайной строкой". Текущий лучший ответ:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
Это отличный метод, но PRNG в random не является криптографически безопасным. Я предполагаю, что многие люди, исследующие этот вопрос, захотят генерировать случайные строки для шифрования или паролей. Вы можете сделать это безопасно, внеся небольшое изменение в приведенный выше код:
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
Использование random.SystemRandom()
вместо just random использует /dev/urandom на компьютерах с * nix и CryptGenRandom()
в Windows. Это криптографически безопасные PRNG. Использование random.choice
вместо random.SystemRandom().choice
в приложении, которому требуется безопасный PRNG, может быть потенциально разрушительным, и, учитывая популярность этого вопроса, я готов поспорить, что ошибка допускалась уже много раз.
Если вы используете python3.6 или выше, вы можете использовать новый модуль secrets, как указано в ответе MSeifert:
''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))
В документации по модулю также обсуждаются удобные способы генерации безопасных токенов и лучшие практики.
Ответ 3
Просто используйте встроенный uuid в Python:
Если UUID подходят для ваших целей, используйте встроенный пакет uuid.
Однострочное решение:
import uuid; uuid.uuid4().hex.upper()[0:6]
Расширенная версия:
Пример:
import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')
Если вам нужен именно ваш формат (например, "6U1S75"), вы можете сделать это следующим образом:
import uuid
def my_random_string(string_length=10):
"""Returns a random string of length string_length."""
random = str(uuid.uuid4()) # Convert UUID format to a Python string.
random = random.upper() # Make all characters uppercase.
random = random.replace("-","") # Remove the UUID '-'.
return random[0:string_length] # Return the random string.
print(my_random_string(6)) # For example, D9E50C
Ответ 4
Более простой, быстрый, но немного менее случайный способ - использовать random.sample
вместо выбора каждой буквы отдельно, если разрешено n повторений, увеличьте вашу случайную базу в n раз, например
import random
import string
char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))
Примечание:
случайная выборка предотвращает повторное использование символов, увеличение размера набора символов делает возможными многократные повторения, но они все равно менее вероятны, чем при чисто случайном выборе. Если мы выберем строку длиной 6 и выберем 'X' в качестве первого символа, в примере выбора шансы получить 'X' для второго символа такие же, как шансы получить 'X' в качестве первого символа. В реализации random.sample шансы получить 'X' в качестве любого последующего символа составляют всего 6/7 шансов получить его в качестве первого символа