[python] 대문자와 숫자를 사용한 임의 문자열 생성

N 크기의 문자열을 생성하고 싶습니다.

다음과 같은 숫자와 대문자 영문자로 구성되어야합니다.

  • 6U1S75
  • 4Z4UKK
  • U911K4

파이썬 방식으로 어떻게 이것을 달성 할 수 있습니까?



답변

한 줄로 답변 :

''.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함수에 포함되지 않으므로 파이썬은 메모리에 목록을 만들지 않고 요소를 하나씩 생성합니다 (자세한 내용은 여기 ).

‘n’곱하기 문자열을 만드는 대신에 elem, 파이썬에게 일련의 문자에서 선택된 임의의 문자를 ‘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'


답변

이 Stack Overflow quesion은 “random string Python”에 대한 Google의 현재 최고 결과입니다. 현재 최고 답변은 다음과 같습니다.

''.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의의 및 CryptGenRandom()Windows에서. 이들은 암호화 적으로 안전한 PRNG입니다. 안전한 PRNG가 필요한 응용 프로그램 random.choice대신에 사용하면 random.SystemRandom().choice잠재적으로 치명적일 수 있으며이 질문의 인기를 감안할 때 이미 실수가 여러 번 이루어진 것 같습니다.

python3.6 이상을 사용하는 경우 MSeifert의 답변에 언급 된 것처럼 새로운 비밀 모듈을 사용할 수 있습니다 .

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

모듈 문서는 또한 안전한 토큰모범 사례생성하는 편리한 방법을 설명 합니다 .


답변

Python의 내장 uuid를 사용하십시오.

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


답변

더 간단하고 빠르지 만 약간 덜 무작위적인 방법은 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 (또는 사용 불가능한 경우 대체)을 사용하고, 필요한 문자 세트가 표시되는지 확인하고, 유니 코드를 사용하거나 사용하지 않고, 연속적인 호출이 고유 한 문자열을 생성하는지 확인하고, 문자열 모듈 문자 클래스 중 하나의 서브 세트를 사용하십시오. 이 모든 것은 제공된 답변보다 많은 코드가 필요합니다. 솔루션을 일반화하려는 다양한 시도에는 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생성기 표현식을 사용하는 경우보다 목록 이해력이 더 빠릅니다 !