निम्नलिखित की तरह 30 अक्षरों का एक यादृच्छिक स्ट्रिंग बनाने के लिए सबसे हल्का तरीका क्या है?
ufhy3skj5nca0d2dfh9hwd2tbk9sw1
और अनुवर्ती की तरह 30 अंकों की एक हेक्साडेसिमल संख्या?
8c6f78ac23b4a7b8c0182d7a89e9b1
निम्नलिखित की तरह 30 अक्षरों का एक यादृच्छिक स्ट्रिंग बनाने के लिए सबसे हल्का तरीका क्या है?
ufhy3skj5nca0d2dfh9hwd2tbk9sw1
और अनुवर्ती की तरह 30 अंकों की एक हेक्साडेसिमल संख्या?
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 केवल यादृच्छिक मॉड्यूल के लिए एक कॉल करता है, एक सूची बनाने या पढ़ने के लिए नहीं है, और फिर स्ट्रिंग प्रारूपण के साथ बाकी है।
string.hexdigits: stackoverflow.com/a/15462293/311288 " string.hexdigitsरिटर्न 0123456789abcdefABCDEF(लोअरकेस और अपरकेस) दोनों, [...]। इसके बजाय, बस उपयोग करें random.choice('0123456789abcdef')।"
getrandbitsबजाय उपयोग करें randrange।
'%030x' % random.getrandbits(60)इससे भी अधिक तेजी से '%030x' % random.randrange(16**30)होने की संभावना है , क्योंकि इसमें बड़े-से-ints से कोई रूपांतरण नहीं करना है
30 अंक हेक्स स्ट्रिंग:
>>> import os,binascii
>>> print binascii.b2a_hex(os.urandom(15))
"c84766ca4a3ce52c3602bbf02ad1f7"
लाभ यह है कि इससे ओएस से सीधे यादृच्छिकता प्राप्त होती है, जो यादृच्छिक () की तुलना में अधिक सुरक्षित और / या तेज हो सकती है, और आपको इसे बीजने की आवश्यकता नहीं है।
import string
import random
lst = [random.choice(string.ascii_letters + string.digits) for n in xrange(30)]
str = "".join(lst)
print str
ocwbKCiuAJLRJgM1bWNV1TPSH0F2Lb
random.SystemRandom().choice
नाटकीय रूप से उन लोगों की तुलना में तेजी से समाधान:
timeit("'%0x' % getrandbits(30 * 4)", "from random import getrandbits")
0.8056681156158447
%timeit '%030x' % randrange(16**30)1000000 लूप देता है, सर्वश्रेष्ठ 3: 1.61 µ प्रति लूप जबकि %timeit '%0x' % getrandbits(30 * 4)1000000 लूप देता है, सर्वश्रेष्ठ 3: 396 एनएस प्रति लूप
In [1]: import random
In [2]: hex(random.getrandbits(16))
Out[2]: '0x3b19'
संयोग से, यह 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]
आप अपनी आवश्यकता के आधार पर आउटपुट लंबाई को अलग करने के लिए रैंडिंट (अंतिम arg) को दिए गए आकार पैरामीटर को बदल सकते हैं। तो, एक 60 चार के लिए:
binascii.b2a_hex(rand.randint(lo, hi, 4).tostring())[:60]
binascii.b2a_hex(np.random.rand(np.ceil(N/16)).view(dtype=int))[:N]जहां N=30।
उस मिश्रण का एक और उत्तर जोड़ना जो @eemz समाधान की तुलना में तेज़ी से कार्य करता है और पूरी तरह से अल्फ़ान्यूमेरिक भी है। ध्यान दें कि यह आपको एक हेक्सिडेसिमल उत्तर नहीं देता है।
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
यह सुनिश्चित करने के लिए है कि सबसे हल्का संस्करण नहीं है, लेकिन यह यादृच्छिक है और यह उस वर्णमाला / लंबाई को समायोजित करना आसान है जिसे आप चाहते हैं:
import random
def generate(random_chars=12, alphabet="0123456789abcdef"):
r = random.SystemRandom()
return ''.join([r.choice(alphabet) for i in range(random_chars)])