Я хочу сгенерировать строку размера N .
Он должен состоять из цифр и заглавных английских букв, таких как:
Как я могу достичь этого пифоническим способом?
Ответ в одной строке:
''.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))
Криптографически более безопасная версия; см. https://stackoverflow.com/a/23728630/2213647:
''.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' times строку elem
, мы попросим Python создать 'n' times случайный символ, выбранный из последовательности символов:
>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'
Поэтому random.choice (chars) для _ в диапазоне (размер)
действительно создает последовательность символов 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'
Это квестование Stack Overflow является текущим лучшим результатом Google для «случайной строки Python». Текущий главный ответ:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
Это отличный метод, но PRNG в случайном порядке не является криптографически безопасным. Я предполагаю, что многие люди, исследующие этот вопрос, захотят генерировать случайные строки для шифрования или паролей. Вы можете сделать это безопасно, внеся небольшое изменение в приведенный выше код:
''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))
Использование random.SystemRandom ()
вместо просто случайного использования / dev / urandom на * nix компьютерах и CryptGenRandom ()
в Windows. Это криптографически безопасные PRNG. Использование random.choice
вместо random.SystemRandom () .choice
в приложении, требующем безопасного PRNG, может быть потенциально разрушительным, и, учитывая популярность этого вопроса, держу пари, что ошибка была допущена уже много раз.
Если вы используете python3.6 или выше, вы можете использовать новый модуль secrets, как указано в Ответе Мейферта:
''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))
Документы модуля также обсуждают удобные способы генерировать безопасные токены и лучшие практики.
Если UUID подходят для ваших целей, используйте встроенный пакет uuid.
импорт 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
Проще, быстрее, но немного менее случайным образом использовать random.sample
вместо выбора каждой буквы отдельно. Если n-повторения разрешены, увеличьте свою случайную основу в n раз, например,.
import random
import string
char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))
Запись: random.sample предотвращает повторное использование символов, умножение размера набора символов делает возможным несколько повторений, но они все еще менее вероятны, чем при чисто случайном выборе. Если мы выберем строку длиной 6 и выберем «X» в качестве первого символа, в примере выбора шансы получить «X» для второго символа совпадают с шансами получить «X» в качестве первый символ. В реализации random.sample шансы получить «X» в качестве любого последующего символа имеют только 6/7 шансов получить его в качестве первого символа
import uuid
lowercase_str = uuid.uuid4().hex
lowercase_str
- это случайное значение, такое как ' cea8b32e00934aaea8c005a35d85a5c0 '
uppercase_str = lowercase_str.upper()
uppercase_str
- это ' CEA8B32E00934AAEA8C005A35D85A5C0 '
Более быстрый, простой и гибкий способ сделать это - использовать модуль strgen
(pip install StringGenerator
).
Сгенерируйте 6-символьную случайную строку с заглавными буквами и цифрами:
>>> from strgen import StringGenerator as SG
>>> SG("[\u\d]{6}").render()
u'YZI2CI'
Получить уникальный список:
>>> SG("[\l\d]{10}").render_list(5,unique=True)
[u'xqqtmi1pOk', u'zmkWdUr63O', u'PGaGcPHrX2', u'6RZiUbkk2i', u'j9eIeeWgEF']
Гарантия один «специальный» символ в строке:
>>> SG("[\l\d]{10}&[\p]").render()
u'jaYI0bcPG*0'
Случайный цвет HTML:
>>> SG("#[\h]{6}").render()
u'#CEdFCa'
так далее.
Нам нужно знать, что это:
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
может не иметь цифры (или заглавного символа) в ней.
strgen
быстрее во времени разработки, чем любое из вышеперечисленных решений. Решение от Ignacio является самым быстрым временем выполнения и является правильным ответом с использованием стандартной библиотеки Python. Но вы вряд ли когда-либо будете использовать его в такой форме. Вы захотите использовать SystemRandom (или запасной вариант, если он недоступен), убедиться, что представлены необходимые наборы символов, использовать unicode (или нет), убедиться, что последовательные вызовы создают уникальную строку, используют подмножество одного из классов символов строкового модуля, так далее. Все это требует гораздо больше кода, чем в предоставленных ответах. Различные попытки обобщить решение имеют ограничения, которые strgen решает с большей краткостью и выразительной силой, используя простой язык шаблонов.
Это на PyPI:
pip install StringGenerator
Раскрытие информации: я автор модуля strgen.
Начиная с Python 3.6, вы должны использовать модуль secrets
, если вам нужно, чтобы он был криптографически защищен вместо модуля random
(в противном случае этот ответ идентичен ответу @ Ignacio Vazquez-Abrams):
from secrets import choice
import string
''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])
Еще одно примечание: в случае str.join
понимание списка происходит быстрее, чем использование выражения генератора!
На основании другого ответа Stack & nbsp; Overflow, Самый легкий способ создать случайную строку и случайное шестнадцатеричное число , лучшая версия, чем принятый ответ, будет:
('%06x' % random.randrange(16**6)).upper()
намного быстрее.
Я думал, что никто еще не ответил на это, лол! Но, эй, вот мой собственный подход к этому:
import random
def random_alphanumeric(limit):
#ascii alphabet of all alphanumerals
r = (range(48, 58) + range(65, 91) + range(97, 123))
random.shuffle(r)
return reduce(lambda i, s: i + chr(s), r[:random.randint(0, len(r))], "")
Если вам нужна случайная строка, а не псевдослучайная , вы должны использовать os.urandom
как источник
from os import urandom
from itertools import islice, imap, repeat
import string
def rand_string(length=5):
chars = set(string.ascii_uppercase + string.digits)
char_gen = (c for c in imap(urandom, repeat(1)) if c in chars)
return ''.join(islice(char_gen, None, length))
Этот метод немного быстрее и немного более раздражает, чем метод 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')
.create генератор, который вынимает 5-битные числа одновременно 0...31 пока никто не ушел. .join () результаты генератора на случайном числе с правильными битами.. С Timeit для 32-символьных строк время было:
[('generate_with_random_choice', 28.92901611328125),
('generate_with_randbits', 20.0293550491333)]
.но для 64 строк символов, randbits проигрывает;).. Я бы, наверное, никогда не использовал этот подход в производственном коде, если бы мне не нравились мои коллеги.
редактировать: обновлять в соответствии с вопросом (только заглавные и цифры) и использовать побитовые операторы & и > > вместо% и //
Я бы сделал это так:
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) )
Используйте функцию Numpy random.choice ()
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
>>> 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
Для тех из вас, кто любит функциональный питон:
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'
селектор по умолчанию - «выбор», который может выбирать один и тот же символ несколько раз для каждого фрагмента, если вместо этого вы хотите, чтобы один и тот же член выбирался не чаще одного раза для каждого фрагмента, то одно возможное использование:
>>> 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
, который извлекает следующий полностью сгенерированный кусок, при условии, что этот пример кажется немного громоздким, и это , ...
(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
это взгляд на ответ Анурага Унияла и то, над чем я работал.
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()
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, длина) Это простой алгоритм, который легко понять. он использует список, чтобы вы могли отбрасывать символы, которые вам не нужны.
>>> 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' ' ' '.
Надеюсь, это поможет!