একটি এলোমেলো স্ট্রিং এবং এলোমেলো হেক্সাডেসিমাল সংখ্যা তৈরির সর্বাধিক হালকা ওজনের উপায়


94

নিম্নলিখিতগুলির মতো 30 টি অক্ষরের এলোমেলো স্ট্রিং তৈরির সবচেয়ে হালকা উপায় কী?

ufhy3skj5nca0d2dfh9hwd2tbk9sw1

এবং অনুসরণের মতো 30 ডিজিটের একটি হেক্সাডেসিমাল সংখ্যা?

8c6f78ac23b4a7b8c0182d7a89e9b1


4
কীভাবে (কেন?) উত্তর (উত্তম তৈরি করা) কোনওটিই গৃহীত হয়নি?
r2evans

উত্তর:


124

আমি হেক্স আউটপুট জন্য একটি দ্রুত পেয়েছি। উপরের মত একই টি 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 কেবল এলোমেলো মডিউলে একটি কল করে, কোনও তালিকা তৈরি বা পড়তে হয় না এবং তারপরে বাকী স্ট্রিং ফর্ম্যাটিংয়ের সাথে থাকে।


4
ভাল লাগল কেবলমাত্র 30 হেক্স ডিজিট দীর্ঘ দীর্ঘ এলোমেলো উত্পন্ন করুন এবং এটি মুদ্রণ করুন। সুস্পষ্ট যখন নির্দেশিত। সুন্দর.
ইয়েজ

আকর্ষণীয়, আমি একধরণের ভুলে গেছি যে পাইথন (এবং এলোমেলো মডিউল) স্থানীয়ভাবে বিগিন্টগুলি পরিচালনা করে।
10'র সাঁকো ump

4
ব্যবহারের জন্য নিচের yaronf এর উত্তর দেখুন string.hexdigits: stackoverflow.com/a/15462293/311288 " string.hexdigitsআয় 0123456789abcdefABCDEF(উভয় ছোট হাতের এবং বড় হাতের), [...] পরিবর্তে, শুধু ব্যবহার। random.choice('0123456789abcdef')।"
থমাস

4
আরও দ্রুততর করার getrandbitsপরিবর্তে ব্যবহার করুন randrange
রবিনস্ট

@robinst একটি ভাল পয়েন্ট আছে। '%030x' % random.getrandbits(60)এর চেয়েও দ্রুততর '%030x' % random.randrange(16**30), সম্ভবত এটির জন্য বড়-ইনসটে / থেকে কোনও রূপান্তর করতে হবে না
ড্যান লেন্সকি

79

30 ডিজিটের হেক্স স্ট্রিং:

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

সুবিধাটি হ'ল এটি সরাসরি ওএস থেকে এলোমেলোতা পায় যা র্যান্ডম () এর চেয়ে বেশি সুরক্ষিত এবং / অথবা দ্রুত হতে পারে এবং আপনার এটি বীজ করতে হবে না।


এটি আকর্ষণীয়, এবং সম্ভবত তিনি চান 30 ডিজিটের হেক্স নম্বর তৈরির জন্য একটি ভাল পছন্দ। সম্ভবত আলফানিউমেরিক স্ট্রিং উত্পন্ন করতে ইউরানডম এবং স্লাইস অপারেটর ব্যবহার করতে পারেন।
ইয়েজ

আমি বিনাসেইয়ের অন্যান্য ক্রিয়াকলাপগুলি একবার দেখেছিলাম, তাদের বেস বেস 64৪ এবং ইউয়েনকোড রয়েছে তবে তার প্রথম ধরণের স্ট্রিং তৈরির উপায় নেই (বেস ৩))।
wump

4
এটি কি এলোমেলো / যথেষ্ট অনন্য, বলার জন্য, সেশন টোকেনগুলিতে ব্যবহার করার মতো?
মোড়গুলি

4
উত্তর: নং উত্তরটি খুঁজে
session-

কিভাবে দৈর্ঘ্য নির্দিষ্ট করে?
3kstc

53

পাই .6..6 + এ, অন্য বিকল্পটি হ'ল নতুন মানক secretsমডিউলটি ব্যবহার করা :

>>> import secrets
>>> secrets.token_hex(15)
'8d9bad5b43259c6ee27d9aadc7b832'
>>> secrets.token_urlsafe(22)   # may include '_-' unclear if that is acceptable
'teRq7IqhaRU0S3euX1ji9f58WzUkrg'

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

6
এবং এলোমেলো.চয়েস (স্ট্রিং.হেক্সডিজিটস)
ইয়েজ

4
কেউ আরও ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত হতে পারেrandom.SystemRandom().choice
ব্রায়ান এম হান্ট

4
এক্সরেঞ্জ () ব্যাপ্তি হওয়া উচিত () - নেম এরির: নাম 'এক্সরঞ্জ' সংজ্ঞায়িত করা হয়নি
কালেব ব্রামওয়েল

অজরঞ্জ পাইথন ২.x-এ সঠিক (এবং সাধারণত আরও ভাল)
জেসিডিয়ার ২৩

25

এগুলির চেয়ে নাটকীয়ভাবে দ্রুত সমাধান:

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

একটি ব্যবহারকারীকে সঠিক বেসলাইন পেতে একই মেশিনে সমস্ত পদ্ধতি ব্যবহার করতে হবে। হার্ডওয়্যার চশমা একটি বড় পার্থক্য করতে পারে। >>>> টাইমিট.টাইমাইট ("'% 0x'% গেট্র্যান্ডবেটস (30 * 4)", "এলোমেলো আমদানির গেট্র্যান্ডবিটস থেকে") 0.2471246949999113 </pre>
পিটি

আপনাকে ধন্যবাদ, উপরের অন্যদের তুলনায় এটি অনেক দ্রুত। %timeit '%030x' % randrange(16**30)1000000 লুপ %timeit '%0x' % getrandbits(30 * 4)দেয়, 3
টির মধ্যে

15

দ্রষ্টব্য: random.choice(string.hexdigits)ভুল, কারণ string.hexdigitsআয় 0123456789abcdefABCDEF(ছোট এবং বড় উভয়ই), সুতরাং আপনি একটি পক্ষপাতমূলক ফলাফল পাবেন, হেক্স ডিজিটের 'সি' দ্বিগুণ '7' হিসাবে প্রদর্শিত হওয়ার সম্ভাবনা দ্বিগুণ। পরিবর্তে, শুধু ব্যবহার করুন random.choice('0123456789abcdef')


6

অন্য পদ্ধতি:

from Crypto import Random
import binascii

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

কথাটি হ'ল: বাইট মান সর্বদা হেক্সের মানের সমান


5

এক-লাইন ফাংশন:

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)

3
In [1]: import random                                    

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

এফওয়াইআই: এই উত্তরটি নিম্ন-মানের হিসাবে চিহ্নিত করা হয়েছে, আপনি এটি উন্নতি করতে চাইতে পারেন।
ওগুজ ইসমাইল

উন্নতির জন্য কোন পরামর্শ?
বব

কোন ধারনা নাই. আমি কেবল ভেবেছিলাম আপনার এটি জানা উচিত
oguz

2

ঘটনাক্রমে, 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

2

জেসিডির যা উল্লেখ করেছেন তার তুলনায় দ্রুততর একটি রয়েছে। এটি তার দ্রুততম পদ্ধতির ~ 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
ড্যান-ম্যান

@ ড্যান-ম্যান এই alচ্ছিক পদ্ধতির জন্য ধন্যবাদ। তবে, আমি দেখতে পাচ্ছি যে এটি কমপক্ষে 5x বেশি সময় ব্যয় করে। আপনিও কি তা খেয়াল করেন?
ইথান

0

@ মিশ্রণের সমাধানের চেয়ে দ্রুত সঞ্চালিত মিশ্রণটিতে আরও একটি উত্তর যুক্ত করা এবং এটি সম্পূর্ণ বর্ণানুক্রমিকও নোট করুন যে এটি আপনাকে একটি হেক্সিডিসিমাল উত্তর দেয় না

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

0

এটি নিশ্চিতভাবে সবচেয়ে হালকা ভার্সন নয়, তবে এটি এলোমেলো এবং আপনি যে বর্ণমালা / দৈর্ঘ্যটি চান তা সামঞ্জস্য করা সহজ:

import random

def generate(random_chars=12, alphabet="0123456789abcdef"):
    r = random.SystemRandom()
    return ''.join([r.choice(alphabet) for i in range(random_chars)])
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.