programing

무작위 문자열과 무작위 16진수 숫자를 만드는 가장 가벼운 방법

lastmoon 2023. 8. 15. 11:24
반응형

무작위 문자열과 무작위 16진수 숫자를 만드는 가장 가벼운 방법

다음과 같이 30자의 임의 문자열을 만드는 가장 가벼운 방법은 무엇입니까?

uhy3skj5nca0d2dfh9hwd2tbk9sw1

그리고 다음과 같은 30자리의 16진수 숫자는?

8c6f78ac23b4a7b8c0182d7a89e9b1

육각 출력을 위해 더 빠른 것을 구했습니다.위와 동일한 t1 및 t2 사용:

>>> t1 = timeit.Timer("''.join(random.choice('0123456789abcdef') for n in xrange(30))", "import random")
>>> t2 = timeit.Timer("binascii.b2a_hex(os.urandom(15))", "import os, binascii")
>>> t3 = timeit.Timer("'%030x' % random.randrange(16**30)", "import random")
>>> for t in t1, t2, t3:
...     t.timeit()
... 
28.165037870407104
9.0292739868164062
5.2836320400238037

t3임의 모듈에 한 번의 호출만 수행하고 목록을 작성하거나 읽을 필요가 없으며 나머지는 문자열 형식으로 수행합니다.

30자리 16진수 문자열:

>>> import os,binascii
>>> print binascii.b2a_hex(os.urandom(15))
"c84766ca4a3ce52c3602bbf02ad1f7"

이점은 OS에서 직접 랜덤성을 얻을 수 있다는 점입니다. 랜덤()보다 안전하고 빠르며 시드할 필요가 없습니다.

Py3.6+의 또 다른 옵션은 새로운 표준을 사용하는 것입니다.secrets모듈:

>>> import secrets
>>> secrets.token_hex(15)
'8d9bad5b43259c6ee27d9aadc7b832'
>>> secrets.token_urlsafe(30*3//4) # see notes
'teRq7IqhaRU0S3euX1ji9f58WzUkrg'

참고:token_urlsafe()base64 인코딩을 사용합니다. 즉, 요청된 수를 다음과 같이 줄입니다.3//4다음을 포함할 수도 있습니다._-그것이 받아들여질 수 있는지 확실하지 않은.

import string
import random
lst = [random.choice(string.ascii_letters + string.digits) for n in xrange(30)]
s = "".join(lst)
print s
ocwbKCiuAJLRJgM1bWNV1TPSH0F2Lb

여기 있는 솔루션보다 훨씬 빠른 솔루션 속도가 빠릅니다.

timeit("'%0x' % getrandbits(30 * 4)", "from random import getrandbits")
0.8056681156158447

참고:random.choice(string.hexdigits)틀렸습니다, 왜냐하면string.hexdigits돌아온다0123456789abcdefABCDEF(소문자와 대문자 모두), 16진수 'c'가 숫자 '7'의 두 배로 나타날 가능성이 있는 편향된 결과를 얻을 수 있습니다.대신, 그냥 사용하세요.random.choice('0123456789abcdef').

In [1]: import random                                    

In [2]: hex(random.getrandbits(16))                      
Out[2]: '0x3b19'

다른 방법:

from Crypto import Random
import binascii

my_hex_value = binascii.hexlify(Random.get_random_bytes(30))

포인트는 바이트 값이 항상 16진수 값과 같다는 것입니다.

한 줄 함수:

import random
import string

def generate_random_key(length):
    return ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(length))

print generate_random_key(30)

참고로, 이것은 사용한 결과입니다.timeit제안된 두 가지 접근 방식에 대해 설명합니다.

사용.random.choice():

>>> t1 = timeit.Timer("''.join(random.choice(string.hexdigits) for n in xrange(30))", "import random, string")
>>> t1.timeit()
69.558588027954102

사용.binascii.b2a_hex():

>>> t2 = timeit.Timer("binascii.b2a_hex(os.urandom(15))", "import os, binascii")
>>> t2.timeit()
16.288421154022217

jcdyer가 언급한 것과 비교하면 빠른 것이 있습니다.이것은 그의 가장 빠른 방법의 ~50%를 필요로 합니다.

from numpy.random.mtrand import RandomState
import binascii
rand = RandomState()

lo = 1000000000000000
hi = 999999999999999999
binascii.b2a_hex(rand.randint(lo, hi, 2).tostring())[:30]

>>> timeit.Timer("binascii.b2a_hex(rand.randint(lo,hi,2).tostring())[:30]", \
...                 'from __main__ import lo,hi,rand,binascii').timeit()
1.648831844329834         <-- this is on python 2.6.6
2.253110885620117         <-- this on python 2.7.5

base64에서 원하는 경우:

binascii.b2a_base64(rand.randint(lo, hi, 3).tostring())[:30]

randint(마지막 arg)로 전달된 size 파라미터를 변경하여 요구 사항에 따라 출력 길이를 변경할 수 있습니다.그래서 60캐런의 경우:

binascii.b2a_hex(rand.randint(lo, hi, 4).tostring())[:60]

이 버전은 가장 가벼운 버전은 아니지만 랜덤이며 원하는 알파벳/길이를 쉽게 조정할 수 있습니다.

import random

def generate(random_chars=12, alphabet="0123456789abcdef"):
    r = random.SystemRandom()
    return ''.join([r.choice(alphabet) for i in range(random_chars)])

@emz 솔루션보다 더 빠르게 수행되며 완전한 영숫자로 구성된 혼합에 하나의 답변을 추가합니다.이것은 16진수 답을 제공하지 않습니다.

import random
import string

LETTERS_AND_DIGITS = string.ascii_letters + string.digits

def random_choice_algo(width):
  return ''.join(random.choice(LETTERS_AND_DIGITS) for i in range(width))

def random_choices_algo(width):
  return ''.join(random.choices(LETTERS_AND_DIGITS, k=width))


print(generate_random_string(10))
# prints "48uTwINW1D"

빠른 기준 산출량

from timeit import timeit
from functools import partial

arg_width = 10
print("random_choice_algo", timeit(partial(random_choice_algo, arg_width)))
# random_choice_algo 8.180561417000717
print("random_choices_algo", timeit(partial(random_choices_algo, arg_width)))
# random_choices_algo 3.172438014007639

언급URL : https://stackoverflow.com/questions/2782229/most-lightweight-way-to-create-a-random-string-and-a-random-hexadecimal-number

반응형