Вопрос-Ответ

Random string generation with upper case letters and digits

Генерация случайных строк с заглавными буквами и цифрами

Как мне сгенерировать строку размера 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 шансов получить его в качестве первого символа

python string