নিম্নলিখিতগুলির মতো 30 টি অক্ষরের এলোমেলো স্ট্রিং তৈরির সবচেয়ে হালকা উপায় কী?
ufhy3skj5nca0d2dfh9hwd2tbk9sw1
এবং অনুসরণের মতো 30 ডিজিটের একটি হেক্সাডেসিমাল সংখ্যা?
8c6f78ac23b4a7b8c0182d7a89e9b1
উত্তর:
আমি হেক্স আউটপুট জন্য একটি দ্রুত পেয়েছি। উপরের মত একই টি 1 এবং টি 2 ব্যবহার করে:
>>> 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), সম্ভবত এটির জন্য বড়-ইনসটে / থেকে কোনও রূপান্তর করতে হবে না
30 ডিজিটের হেক্স স্ট্রিং:
>>> import os,binascii
>>> print binascii.b2a_hex(os.urandom(15))
"c84766ca4a3ce52c3602bbf02ad1f7"
সুবিধাটি হ'ল এটি সরাসরি ওএস থেকে এলোমেলোতা পায় যা র্যান্ডম () এর চেয়ে বেশি সুরক্ষিত এবং / অথবা দ্রুত হতে পারে এবং আপনার এটি বীজ করতে হবে না।
পাই .6..6 + এ, অন্য বিকল্পটি হ'ল নতুন মানক secretsমডিউলটি ব্যবহার করা :
>>> import secrets
>>> secrets.token_hex(15)
'8d9bad5b43259c6ee27d9aadc7b832'
>>> secrets.token_urlsafe(22) # may include '_-' unclear if that is acceptable
'teRq7IqhaRU0S3euX1ji9f58WzUkrg'
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 লুপ %timeit '%0x' % getrandbits(30 * 4)দেয়, 3
দ্রষ্টব্য: random.choice(string.hexdigits)ভুল, কারণ string.hexdigitsআয় 0123456789abcdefABCDEF(ছোট এবং বড় উভয়ই), সুতরাং আপনি একটি পক্ষপাতমূলক ফলাফল পাবেন, হেক্স ডিজিটের 'সি' দ্বিগুণ '7' হিসাবে প্রদর্শিত হওয়ার সম্ভাবনা দ্বিগুণ। পরিবর্তে, শুধু ব্যবহার করুন random.choice('0123456789abcdef')।
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
জেসিডির যা উল্লেখ করেছেন তার তুলনায় দ্রুততর একটি রয়েছে। এটি তার দ্রুততম পদ্ধতির ~ 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
আপনি যদি বেস 64 তে চান:
binascii.b2a_base64(rand.randint(lo, hi, 3).tostring())[:30]
আপনার প্রয়োজনীয়তার উপর ভিত্তি করে আউটপুট দৈর্ঘ্যের পরিবর্তনের জন্য আপনি রেন্ডেন্ট (শেষ আরগ) এ পাস করা আকারের প্যারামিটার পরিবর্তন করতে পারেন। সুতরাং, 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।
@ মিশ্রণের সমাধানের চেয়ে দ্রুত সঞ্চালিত মিশ্রণটিতে আরও একটি উত্তর যুক্ত করা এবং এটি সম্পূর্ণ বর্ণানুক্রমিকও নোট করুন যে এটি আপনাকে একটি হেক্সিডিসিমাল উত্তর দেয় না ।
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)])