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


1335

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

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

  • 6U1S75
  • 4Z4UKK
  • U911K4

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


11
이것은 매우 인기있는 질문입니다. 전문가가 상위 3 개의 답변에 대해 이러한 난수의 고유성, 즉 문자열 크기 범위에 대한 충돌 확률 (예 : 6 ~ 16)을 추가하기를 바랍니다.
사용자

8
@buffer 가능한 조합의 수를 계산하는 것은 쉽습니다. 10의 숫자 + 26 개의 문자 = 36 개의 가능한 문자, 6의 거듭 제곱 (문자열 길이)은 약 20 억입니다. 임의의 값에 대한 나의 경험 법칙은 "지구상의 모든 인간에 대한 값을 생성하면 각각 얼마나 많은 값을 가질 수 있습니까?"입니다. 이 경우 개인당 하나의 값보다 작으므로 사용자 또는 개체를 식별하는 데 너무 적은 문자입니다. 한 가지 대안은 소문자를 추가하여 62 ^ 6 = 거의 570 억 개의 고유 한 값에 도달하는 것입니다.
Blixt

1
그리고 세계 인구를 생각하는 것은 어리석은 것처럼 보일 수 있지만 잠재적 충돌에 대한 거대한 버퍼를 원하기 때문입니다. 생일 문제를 참조하십시오 : en.wikipedia.org/wiki/Birthday_problem
Blixt

1
@buffer, 당신은 이 답변에 관심 있을 것 입니다.
Anish Ramaswamy

이 이름을 "암호화 보안 임의 문자열 생성 ..."으로 바꾸지 않아야 합니까?
smci

답변:


2540

한 줄로 답변 :

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

7
@jorelli : 그것은 목록 이해가 아닙니다; 생성기 표현입니다.
Ignacio Vazquez-Abrams

2
@ joreilli : 답변에 이것에 대한 간단한 메모와 iterable, list comprehension, generator 및 yield 키워드에 대한 더 자세한 답변에 대한 링크를 추가했습니다.
전자 Satis

1
나는 대체 할 것 range으로 xrange.
Dr. Jan-Philip Gehrcke

1
매우 유용한. 흥미롭게도 Django는 암호 및 CSRF 토큰을 생성하기 위해이 코드를 사용하고 있습니다. 당신은 교체해야하지만 random함께 random.SystemRandom(): github.com/django/django/blob/...
사용자

1
@ Chiel92 random.sample는 OP의 요구 사항이 아닌 문자를 반복 할 가능성없이 대체없이 샘플을 만듭니다. 나는 그것이 대부분의 응용 프로그램에 바람직하다고 생각하지 않습니다.
온톨로지

557

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

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


3
예, 공식 표준 라이브러리 random는 다음과 같이 경고합니다. " 경고 :이 모듈의 의사 난수 생성기는 보안 목적으로 사용해서는 안됩니다. 암호로 안전한 의사 난수 생성기가 필요한 경우 os.urandom () 또는 SystemRandom을 사용하십시오. " 다음은 참조입니다 : random.SystemRandomos.urandom
lord63. j

4
좋은 대답입니다. 작은 참고 : string.uppercase로케일 세트에 따라 예기치 않은 결과가 발생할 수 있도록 변경했습니다 . 사용 string.ascii_uppercase(또는 string.ascii_letters + string.digits대신 base36의 base62 용)은 인코딩이 포함되는 경우에 안전하다.
Blixt

작은 메모- 후자는 메모리 내 목록을 생성하고 전자는 반복자를 생성 하므로 xrange대신 사용 하는 것이 좋습니다 range.
guyarad

2
무작위 찌르기는 항상 독특합니까? 기본 키를 사용하고 싶었습니다.
shakthydoss

3
@shakthydoss : 아뇨. 그것은하는 임의의 문자열입니다 "AAA000"및 다음 "AAA000", 반환 할 수 있습니다 또한 임의의 문자열입니다. 고유성 검사를 명시 적으로 추가해야합니다.
usr2564301

189

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

14
+1 질문 뒤에 생각하기. uuid1과 uuid4의 차이점을 간단히 설명 할 수 있습니다.
Thomas Ahle

1
uuid1을 연속으로 세 번 수행하면 다음과 같은 결과가 나타납니다. 처음 8 문자는 다르고 나머지는 동일합니다). uuid4의 경우는 해당되지 않습니다
Chase Roberts

9
uui1 : 호스트 ID, 시퀀스 번호 및 현재 시간에서 UUID를 생성합니다. uuid4 : 임의의 UUID를 생성합니다.
Bijan

7
문자열 캐스팅 및 하이픈 교체를 건너 뛰려면 my_uuid.get_hex () 또는 uuid.uuid4 (). get_hex ()를 호출하면 하이픈이없는 uuid에서 생성 된 문자열을 반환합니다.
dshap

8
UUID를 자르는 것이 좋은 생각입니까? 작은 크기에 따라 string_length충돌 가능성이 문제가 될 수 있습니다.
사용자

44

더 간단하고 빠르지 만 약간 덜 무작위적인 방법은 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입니다.


8
이 방법은 나쁘지는 않지만 sample동일한 문자를 두 번 나열하지 않으므로 각 문자를 개별적으로 선택하는 것만 큼 무작위 는 아닙니다. 또한 물론 N보다 높을 경우 실패합니다 36.
bobince

주어진 유스 케이스 (반복이 정상이 아닌 경우)에 대해서는 여전히 최선의 해결책이라고 말할 것입니다.
Anurag Uniyal

3
예제 중 하나에 반복이 있으므로 반복을 허용하지 않으려는 것 같습니다.
Mark Byers

5
random.sample이 문자 재사용을 방해하는 경우 문자 세트의 크기를 곱하면 여러 번 반복 할 수 있지만 여전히 무작위로 선택할 가능성 은 적습니다 . 길이가 6 인 문자열로 가서 첫 번째 문자로 'X'를 선택하면, 선택 예제에서 두 번째 문자에 대해 'X'를 얻는 확률은 'X'를 얻는 확률과 동일합니다. 첫 번째 캐릭터. random.sample 구현에서 후속 문자로 'X'를 얻을 가능성은 첫 번째 문자로 얻을 확률이 5/6에 불과합니다.
pcurry

1
생성 된 문자열을 이동할 때 특정 문자가 반복 될 가능성이 줄어 듭니다. 26 개의 대문자와 10 자리에서 6 개의 문자열을 생성하고 각 문자를 임의로 임의로 선택하면 특정 문자열은 빈도 1 / (36 ^ 6)로 발생합니다. 'FU3WYE'및 'XXXXXX'생성 가능성은 동일합니다. 샘플 구현에서 'XXXXXX'생성 가능성은 (1 / (36 ^ 6)) * ((6/6) * (5/6) * (4/6) * (3/6) * (2 random.sample의 대체 기능이 아니기 때문에 / 6) * (1/6)). 'XXXXXX'는 샘플 구현에서 324 배 더 적습니다.
pcurry

32
import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str 같은 임의의 값입니다 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str 이다 'CEA8B32E00934AAEA8C005A35D85A5C0'


2
uppercase_str[:N+1]
Yajo

@Yajo 네, 슬라이싱 사용을 제한 할 수 있습니다
Savad KP

2
@ Yajo : 아니요, 16 진수 값을 슬라이스하고 싶지 않습니다. 대문자와 숫자의 전체 시퀀스와 비교하여 엔트로피를 제거합니다. 아마도 base32-encode 대신 값을 인코딩하십시오 (16 ** n보다 약간 더 나은 엔트로피를 36 ** n에서 32 ** n으로 줄였습니다).
Martijn Pieters

19

더 빠르고 쉽고 유연한 방법은 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 모듈의 저자입니다.


12

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생성기 표현식을 사용하는 경우보다 목록 이해력이 더 빠릅니다 !



9

의사 임의 문자열이 아닌 임의 문자열이 필요한 경우 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))

3
os.urandom의사 는 어떻게 무작위가 아닌가? 더 무작위 인 숫자를 생성하기 위해 더 나은 알고리즘을 사용하고있을 수 있지만 여전히 의사 난수입니다.
Tyilo

@Tyilo, 나는 사이의 차이를 알고 /dev/random/dev/urandom. 문제는 /dev/random엔트로피가 충분하지 않을 때 차단되어 유용성을 제한한다는 것입니다. A에 대한 한 번 패드 /dev/urandom 좋은 것만으로는 충분하지 않습니다,하지만 난 그게 더 나은 여기 의사 랜덤보다는 생각합니다.
John La Rooy

1
나는 두 말할 것입니다 /dev/random/dev/urandom의사 랜덤이지만, 그것은 당신의 정의에 달려 있습니다.
Tyilo

9

아직 아무도 대답하지 않았다고 생각했습니다! 그러나 이봐, 내 자신의 일이 있습니다 :

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

4
나는 이것을 투표로 표명하지는 않지만 그렇게 간단한 작업을하기에는 너무 복잡하다고 생각합니다. 반환 표현은 괴물입니다. 단순보다 복잡합니다.
Carl Smith

12
@CarlSmith, 사실 내 솔루션은 작업에 약간의 과잉으로 보이지만 다른 간단한 솔루션을 알고 있었고 좋은 답변을 얻을 수있는 대안 경로를 찾고 싶었습니다. 자유가 없으면 창의력이 위험에 빠지므로 계속해서 게시했습니다.
nemesisfixx

7

이 메소드는 Ignacio가 게시 한 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')

... 0시 31 분에 5 비트 숫자를 추출하는 생성기를 생성합니다.

... join () 올바른 비트를 가진 난수에 대한 생성기 결과

Timeit를 사용하면 32 자 문자열의 타이밍은 다음과 같습니다.

[('generate_with_random_choice', 28.92901611328125),
 ('generate_with_randbits', 20.0293550491333)]

... 64 문자 문자열의 경우 randbits가 손실됩니다.)

동료를 싫어하는 경우가 아니면 프로덕션 코드에서이 방법을 사용하지 않을 것입니다.

편집 : 질문 (대문자 및 숫자 만)에 맞게 업데이트되었으며 % 및 // 대신 비트 연산자 & 및 >>를 사용하십시오.


5

나는 이렇게 할 것입니다 :

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

5

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


1
python stdlib random 대신 numpy random을 사용해야하는 이유는 무엇입니까?
Pax0r

길이, 변수 확률 및 대체 선택과 같은 인수에 더 많은 옵션을 허용하기 때문입니다.
Mudit Jain

5

때로는 0 (영)과 O (문자 O)가 혼동 될 수 있습니다. 그래서 나는

import uuid
uuid.uuid4().hex[:6].upper().replace('0','X').replace('O','Y')

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

3
그러나이 변형은 모든 문자를 다르게 만듭니다. N이 len (string.ascii_uppercase + string.digits)보다 큰 경우에는 작동하지 않습니다
MarSoft

3

기능적인 파이썬을 즐기는 사람들을 위해 :

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)

시퀀스를 즉석에서 생성하려면 간단히 join to 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다음에 완전히 생성 된 청크를 가져 오는 호출 을 호출합니다. 이 예제는 약간 성가신 것처럼 보이며 ...


3

(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  

3

이것은 Anurag 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()

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

도움이 되었기를 바랍니다!


멋지지만 range(num)대신 사용할 수 있고 str은 string 일 수 있습니다 str += random.choice(chars).
sashk

2
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

2
이 코드는 질문에 대답 할 수 있지만, 질문에 대한 이유 및 / 또는 방법 에 대한 추가 컨텍스트를 제공 하면 장기적인 가치가 크게 향상됩니다. 제발 편집 약간의 설명을 추가 할 답변을.
Toby Speight

2
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="")

여기서 문자열의 길이는 for 루프 즉, range (1, length)의 i에 대해 변경할 수 있습니다. 이해하기 쉬운 간단한 알고리즘입니다. 필요없는 문자를 버릴 수 있도록 list를 사용합니다.


1

간단한 것 :

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

0

다음 옵션을 제안하고 싶습니다.

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]

0

두 가지 방법 :

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


벤치 마크 :

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

첫 번째 방법의 성능이 더 좋습니다.


0

나는 거의 모든 답변을 갔지만 그중 어느 것도 더 쉽게 보이지 않습니다. 무작위 암호를 만드는 데 일반적으로 사용되는 passgen 라이브러리 를 사용해 보는 것이 좋습니다 .

길이, 문장 부호, 숫자, 문자대소 문자를 임의로 선택하여 문자열을 생성 할 수 있습니다 .

사례 코드는 다음과 같습니다.

from passgen import passgen
string_length = int(input())
random_string = passgen(length=string_length, punctuation=False, digits=True, letters=True, case='upper')

0

임의의 16 바이트 ID 포함 문자, 숫자, '_'및 '-'생성

os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))


0

나는 다른 답변을보고 있었고 비밀 문서를 읽는 데 시간이 걸렸습니다.

비밀 모듈은 암호, 계정 인증, 보안 토큰 및 관련 비밀과 같은 데이터 관리에 적합한 암호화 적으로 강력한 난수를 생성하는 데 사용됩니다.

특히, 보안 또는 암호화가 아닌 모델링 및 시뮬레이션을 위해 설계된 랜덤 모듈의 기본 의사 난수 생성기보다 비밀을 사용해야합니다.

제공해야 할 사항을 자세히 살펴보면 Google 드라이브 ID와 같은 ID를 모방하려는 경우 매우 편리한 기능을 발견했습니다.

secrets.token_urlsafe ([nbytes = None])
nbytes의 임의 바이트를 포함하는 임의의 URL 안전 텍스트 문자열을 리턴합니다. 텍스트는 Base64로 인코딩되므로 평균적으로 각 바이트는 약 1.3 자 입니다. nbytes가 없음이거나 제공되지 않은 경우 적절한 기본값이 사용됩니다.

다음과 같이 사용하십시오.

import secrets
import math

def id_generator():
    id = secrets.token_urlsafe(math.floor(32 / 1.3))
    return id

print(id_generator())

32 자 길이의 id를 출력하십시오.

joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk

나는 이것이 OP의 질문과 약간 다르다는 것을 알고 있지만, 내가 찾던 것과 동일한 사용 사례를 찾고있는 많은 사람들에게 여전히 도움이 될 것으로 기대합니다.


-1
import string, random
lower = string.ascii_lowercase
upper = string.ascii_uppercase
digits = string.digits
special = '!"£$%^&*.,@#/?'

def rand_pass(l=4, u=4, d=4, s=4):
    p = []
    [p.append(random.choice(lower)) for x in range(l)]
    [p.append(random.choice(upper)) for x in range(u)]
    [p.append(random.choice(digits)) for x in range(d)]
    [p.append(random.choice(special)) for x in range(s)]
    random.shuffle(p)
    return "".join(p)

print(rand_pass())
# @5U,@A4yIZvnp%51

-2

나는 이것이 더 간단하고 깨끗하다는 것을 알았다.

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을 변경하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.