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

Я хочу создать строку размера N.

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

  • 6U1S75
  • 4Z4UKK
  • U911K4

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

27 ответов


ответ в одну строку:

''.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 ' раз строку 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'

этот вопрос переполнения стека является текущим лучшим результатом Google для "random string 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() вместо того, чтобы просто случайное использование /dev / urandom на * Nix машинах и CryptGenRandom() в Windows. Это криптографически защищенные PRNGs. Используя random.choice вместо random.SystemRandom().choice в приложении, которое требует безопасного PRNG может быть потенциально разрушительным, и учитывая популярность этого вопроса, я уверен, что ошибка была сделана много раз уже.

если вы используете python3.6 или выше, вы можете использовать новый секреты.

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

документы модуля также обсуждают удобное способы генерировать надежные маркеры и лучшие практики.


просто используйте встроенный UUID Python:

если UUIDs в порядке для ваших целей, используйте встроенный 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

более простой, быстрый, но немного менее случайный способ использовать random.sample вместо того, чтобы выбирать каждую букву отдельно, если N-повторения разрешены, увеличьте свой случайный базис в n раз, например

import random
import string

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

Примечание.: случайность.sample предотвращает повторное использование символов, умножение размера набора символов делает возможным несколько повторений, но они все еще менее вероятны, чем в чистом случайном выборе. Если мы идем для строки длины 6, и мы выбираем 'X' в качестве первого символа, в пример выбора: шансы получить " X "для второго символа такие же, как шансы получить" X " в качестве первого символа. В случайный.пример реализации, шансы получить " X " как любой последующий символ только 6/7 шанс получить его в качестве первого символа


import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str является случайным значением, как 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str is 'CEA8B32E00934AAEA8C005A35D85A5C0'


принимая ответ от Игнасио, это работает с Python 2.6:

import random
import string

N=6
print ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

пример:

JQUBT2


более быстрый, простой и гибкий способ сделать это-использовать 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'

etc.

мы должны знать, что это:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

возможно, в нем нет цифры (или символа верхнего регистра).

strgen быстрее во времени разработчика, чем любое из вышеперечисленных решений. Решение от Ignacio является самым быстрым временем выполнения и является правильным ответом с использованием стандартной библиотеки Python. Но вы вряд ли когда-нибудь будете использовать его в такой форме. Вы захотите использовать SystemRandom (или резервный, если он недоступен), убедитесь, что представлены требуемые наборы символов, используйте unicode (или нет), убедитесь, что последовательные вызовы создают уникальную строку, используют подмножество одного из классов символов модуля string и т. д. Все это требует намного больше кода, чем в предоставленных ответах. Различные попытки обобщить решение имеют ограничения, которые strgen решает с большей краткостью и выразительной силой, используя простой язык шаблонов.

это на PyPI:

pip install StringGenerator

раскрытие информации: я автор модуля strgen.


Если вам нужна случайная строка, а не псевдослучайных, вы должны использовать 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))

Я думал, что никто не ответил на это еще lol! Но эй, вот мой собственный идти на это:

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))], "")

на основе другого ответа переполнения стека,самый легкий способ создать случайную строку и случайного шестнадцатеричного числа, лучшая версия, чем принятый ответ:

('%06x' % random.randrange(16**6)).upper()

гораздо быстрее.


этот метод немного быстрее и немного более раздражающего, чем случайный.choice () метод Ignacio posted.

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

# 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 символьных строк, randbits проигрывает ;)

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

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


из 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 чем использование выражения генератора!


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

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.функция выбора ()

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


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

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)

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

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

если вы хотите создать последовательность на лету, просто установите join в identity.

>>> 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 который извлекает следующий полностью сгенерированный кусок, если этот пример кажется немного громоздким, и это так ...


(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  

это взять на себя ответ Анураг Uniyal и то, что я работаю над собой.

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

>>> 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'.

надеюсь, что это помогает!


просто:

import string
import random
character = string.lowercase + string.uppercase + string.digits + string.punctuation
char_len = len(character)
# you can specify your password length here
pass_len = random.randint(10,20)
password = ''
for x in range(pass_len):
    password = password + character[random.randint(0,char_len-1)]
print password

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

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.e для i в диапазоне (1, длина) Это простой алгоритм, который легко понять. он использует список, чтобы вы могли отбросить символы, которые вам не нужны.


Я хотел бы предложить вам следующий вариант:

import crypt
n = 10
crypt.crypt("any sring").replace('/', '').replace('.', '').upper()[-n:-1]

режим параноики:

import uuid
import crypt
n = 10
crypt.crypt(str(uuid.uuid4())).replace('/', '').replace('.', '').upper()[-n:-1]

два метода :

import random, math

def randStr_1(chars:str, length:int) -> str:
    chars *= math.ceil(length / len(chars))
    chars = letters[0:length]
    chars = list(chars)
    random.shuffle(characters)

    return ''.join(chars)

def randStr_2(chars:str, length:int) -> str:
    return ''.join(random.choice(chars) for i in range(chars))


Benchmark:

from timeit import timeit

setup = """
import os, subprocess, time, string, random, math

def randStr_1(letters:str, length:int) -> str:
    letters *= math.ceil(length / len(letters))
    letters = letters[0:length]
    letters = list(letters)
    random.shuffle(letters)
    return ''.join(letters)

def randStr_2(letters:str, length:int) -> str:
    return ''.join(random.choice(letters) for i in range(length))
"""

print('Method 1 vs Method 2', ', run 10 times each.')

for length in [100,1000,10000,50000,100000,500000,1000000]:
    print(length, 'characters:')

    eff1 = timeit("randStr_1(string.ascii_letters, {})".format(length), setup=setup, number=10)
    eff2 = timeit("randStr_2(string.ascii_letters, {})".format(length), setup=setup, number=10)
    print('\t{}s : {}s'.format(round(eff1, 6), round(eff2, 6)))
    print('\tratio = {} : {}\n'.format(eff1/eff1, round(eff2/eff1, 2)))

выход :

Method 1 vs Method 2 , run 10 times each.

100 characters:
    0.001411s : 0.00179s
    ratio = 1.0 : 1.27

1000 characters:
    0.013857s : 0.017603s
    ratio = 1.0 : 1.27

10000 characters:
    0.13426s : 0.151169s
    ratio = 1.0 : 1.13

50000 characters:
    0.709403s : 0.855136s
    ratio = 1.0 : 1.21

100000 characters:
    1.360735s : 1.674584s
    ratio = 1.0 : 1.23

500000 characters:
    6.754923s : 7.160508s
    ratio = 1.0 : 1.06

1000000 characters:
    11.232965s : 14.223914s
    ratio = 1.0 : 1.27

производительность первого метода лучше.


для python 3 строка импорт, случайный

".join (random.выбор(строка.ascii_lowercase + строка.ascii_uppercase + строка.цифры) для _ в диапазоне (15))


Я нашел, что это проще и чище.

str_Key           = ""
str_FullKey       = "" 
str_CharacterPool = "01234ABCDEFfghij~>()"
for int_I in range(64): 
    str_Key = random.choice(str_CharacterPool) 
    str_FullKey = str_FullKey + str_Key 

просто меняет 64 варьировать длину, варьировать CharacterPool делать Альфа только буквенно-цифровой или только цифровой или странные символы или что вы хотите.


Вы можете использовать код

var chars = "ABC123";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, 7) //Change 7 to any number of characters you want in your outcome
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());

        textBox1.Text = result;

это будет случайным выплюнуть случайный 7 буквенно-цифровой шаблон, просто измените 7 на любое число, которое вы хотите, и он будет производить, что много чисел и/или букв.

другой способ написать это следующим образом...

var chars = "ABC123";
var stringChars = new char[7]; //Change 7 to any number of characters you want in your outcome
var random = new Random();

for (int i = 0; i < stringChars.Length; i++)
{

stringChars[i] = chars[random.Next(chars.Length)];

}

var finalString = new String(stringChars);

textBox1.Text = finalstring;`

Я не уверен, как добавить ограничения, такие как сделать его там, где он не позволяет определенным числам и / или буквам быть рядом друг с другом или повторять, например, получение "AAA123", если кто-нибудь знает, как чтобы ограничить результат, чтобы иметь что-то подобное, пожалуйста, прокомментируйте