ऊपरी मामले के अक्षरों और अंकों के साथ यादृच्छिक स्ट्रिंग पीढ़ी


1335

मैं आकार एन की एक स्ट्रिंग उत्पन्न करना चाहता हूं।

यह संख्याओं और बड़े अक्षरों से बना होना चाहिए जैसे कि अंग्रेजी अक्षर:

  • 6U1S75
  • 4Z4UKK
  • U911K4

मैं इसे पाइथोनिक तरीके से कैसे प्राप्त कर सकता हूं ?


11
यह एक बहुत लोकप्रिय प्रश्न है। मैं चाहता हूं कि एक विशेषज्ञ शीर्ष 3 उत्तरों के लिए इन यादृच्छिक संख्याओं की विशिष्टता पर अपनी पकड़ को जोड़ देगा यानी स्ट्रिंग आकार की सीमा के लिए टक्कर की संभावना, 6 से 16 तक कहेंगे।
उपयोगकर्ता

8
@ बफ़र संभव संयोजनों की संख्या की गणना करना आसान है। 10 संख्या + 26 अक्षर = 36 संभावित वर्ण, 6 की शक्ति (स्ट्रिंग की लंबाई) लगभग दो बिलियन के बराबर है। यादृच्छिक मूल्यों के लिए अंगूठे का मेरा नियम है "यदि मैंने पृथ्वी पर प्रत्येक मानव के लिए मान उत्पन्न किए, तो वे प्रत्येक के कितने मूल्य हो सकते हैं?"। इस मामले में, जो प्रति व्यक्ति एक मूल्य से कम होगा, इसलिए यदि यह उपयोगकर्ताओं या वस्तुओं की पहचान करना है, तो यह बहुत कम वर्ण हैं। एक विकल्प निचले मामलों के अक्षरों में जोड़ना होगा, जो आपको 62 ^ 6 = लगभग 57 बिलियन अद्वितीय मानों पर भूमि देता है।
ब्लिक्स

1
और जबकि यह दुनिया की आबादी के बारे में सोचने के लिए मूर्खतापूर्ण लग सकता है, ऐसा सिर्फ इसलिए है क्योंकि आप संभावित टकरावों के लिए एक बड़ा बफर चाहते हैं। जन्मदिन की समस्या देखें: en.wikipedia.org/wiki/Birthday_problem
Blixt

1
@ बफ़र, आपको इस उत्तर में दिलचस्पी होगी ।
अनीश रामास्वामी

क्या इसका नाम बदलकर "क्रिप्टोग्राफिक रूप से सुरक्षित रैंडम स्ट्रिंग जेनरेशन ..." नहीं होना चाहिए ?
1

जवाबों:


2539

एक पंक्ति में उत्तर दें:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

या इससे भी कम पायथन 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समारोह तो अजगर स्मृति में सूची का निर्माण नहीं करता है, लेकिन मक्खी पर तत्वों, द्वारा एक के बाद एक (इस बारे में अधिक उत्पन्न करता है यहाँ )।

स्ट्रिंग के 'एन' बार बनाने के लिए कहने के बजाय elem, हम पायथन को 'एन' बार एक यादृच्छिक चरित्र बनाने के लिए कहेंगे, जो पात्रों के अनुक्रम से लिया गया है:

>>> 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
@ जॉर्ली: यह सूची की समझ नहीं है; यह एक जनरेटर अभिव्यक्ति है।
इग्नासियो वाज़केज़-अब्राम्स

2
@joreilli: मैंने उत्तर में इसके बारे में एक त्वरित नोट जोड़ा, और पुनरावृत्त, सूची समझ, जनरेटर और अंततः उपज कीवर्ड के बारे में अधिक विस्तृत उत्तर के लिए एक लिंक।
ई-सतीस

1
मैं के rangeसाथ बदल देंगे xrange
डॉ। जन-फिलिप गेर्के जुले

1
बहुत उपयोगी। दिलचस्प बात यह है कि, Django पासवर्ड और CSRF टोकन जेनरेट करने के लिए इस कोड का उपयोग कर रहा है। यद्यपि आपको इसके randomसाथ प्रतिस्थापित करना चाहिए random.SystemRandom(): github.com/django/django/blob/…
उपयोगकर्ता

1
@ Chiel92, random.sampleप्रतिस्थापन के बिना नमूने बनाता है, दूसरे शब्दों में, पात्रों को दोहराने की संभावना के बिना, जो ओपी की आवश्यकताओं में नहीं है। मुझे नहीं लगता कि अधिकांश अनुप्रयोगों के लिए यह वांछनीय होगा।
ontologist

557

यह स्टैक ओवरफ्लो quesion "यादृच्छिक स्ट्रिंग पायथन" के लिए वर्तमान शीर्ष 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()* निक्स मशीनों और CryptGenRandom()विंडोज में सिर्फ रैंडम यूज / डेव / यूरेनियम के बजाय का उपयोग करना । ये क्रिप्टोग्राफिक रूप से सुरक्षित PRNG हैं। random.choiceइसके बजाय random.SystemRandom().choiceएक ऐसे अनुप्रयोग का उपयोग करना जिसके लिए एक सुरक्षित PRNG की आवश्यकता होती है, संभावित रूप से विनाशकारी हो सकता है, और इस प्रश्न की लोकप्रियता को देखते हुए, मुझे लगता है कि गलती कई बार पहले ही हो चुकी है।

यदि आप python3.6 या इसके बाद के संस्करण का उपयोग कर रहे हैं, तो आप MSeifert के उत्तर में उल्लिखित नए रहस्य मॉड्यूल का उपयोग कर सकते हैं :

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

मॉड्यूल डॉक्स सुरक्षित टोकन और सर्वोत्तम प्रथाओं को उत्पन्न करने के लिए सुविधाजनक तरीकों पर भी चर्चा करते हैं


3
हां, आधिकारिक मानक पुस्तकालय randomने इसके लिए चेतावनी दी है: " चेतावनी : सुरक्षा उद्देश्यों के लिए इस मॉड्यूल के छद्म यादृच्छिक जनरेटर का उपयोग नहीं किया जाना चाहिए। यदि आपको एक क्रिप्टोग्राफिक रूप से सुरक्षित छद्म-यादृच्छिक संख्या जनरेटर की आवश्यकता है तो os.urandom () या SystemRandom का उपयोग करें। " यहाँ रेफरी है: random.SystemRandom और os.urandom
lord63। j

4
बहुत बढ़िया जवाब। छोटा नोट: आपने इसे बदल दिया है string.uppercaseजिससे स्थानीय सेट के आधार पर अप्रत्याशित परिणाम प्राप्त हो सकते हैं। उपयोग करना string.ascii_uppercase(या string.ascii_letters + string.digitsबेस 36 के बजाय बेस 62 के लिए) उन मामलों में सुरक्षित है जहां एन्कोडिंग शामिल है।
ब्लिक्स

छोटे नोट - बाद के xrangeबजाय उपयोग करने के लिए बेहतर है rangeएक इन-मेमोरी सूची उत्पन्न करता है, जबकि पूर्व एक पुनरावृत्त बनाता है।
मसराद

2
क्या बेतरतीब स्टिंग अद्वितीय होगा? मैं एक प्राथमिक कुंजी का उपयोग करना चाहता था।
shakthydoss

3
@ साकथायडोस: नहीं। यह "AAA000" लौटा सकता है, जो एक यादृच्छिक स्ट्रिंग है, और अगला "AAA000" है, जो एक यादृच्छिक स्ट्रिंग भी है। आपको स्पष्ट रूप से विशिष्टता के लिए एक चेक जोड़ना होगा।
usr2564301

189

बस पायथन के बिलिन यूआईडी का उपयोग करें:

यदि यूयूआईडी आपके उद्देश्यों के लिए ठीक हैं, तो अंतर्निहित यूआईडी पैकेज का उपयोग करें ।

एक पंक्ति समाधान:

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 के बीच अंतर को संक्षेप में बता सकते हैं।
थॉमस अहले

1
अगर मैं एक पंक्ति में तीन बार uuid1 करता हूं तो मुझे मिलता है: d161fd16-ab0f-11e3-9314-00259073e4a8, d3535b56-ab0f-11e3-9314-00259073e4a8, d413be32-ab0f-11e3-9314-9314-9314-9314 पहले 8 चार्ट अलग हैं और बाकी समान हैं)। यह uuid4 के साथ मामला नहीं है
चेस रॉबर्ट्स

9
uui1: एक होस्ट आईडी, अनुक्रम संख्या और वर्तमान समय से एक UUID उत्पन्न करें। uuid4: एक यादृच्छिक UUID उत्पन्न करें।
बिजन

7
यदि आप स्ट्रिंग कास्टिंग और हाइफ़न को बदलना छोड़ना चाहते हैं, तो आप my_uuid.get_hex () या uuid.uuid4 ()। Get_hex () कॉल कर सकते हैं और यह uuid से उत्पन्न एक स्ट्रिंग लौटाएगा जिसमें हाइफ़न नहीं है।
dsp

8
क्या UUID को अलग करना एक अच्छा विचार है? कितना छोटा string_lengthहै पर निर्भर करता है, टकराव की संभावना एक चिंता का विषय हो सकता है।
उपयोगकर्ता

44

random.sampleप्रत्येक अक्षर को अलग-अलग चुनने के बजाय एक सरल, तेज़ लेकिन थोड़ा कम यादृच्छिक तरीके से उपयोग किया जाता है, यदि n-repetitions की अनुमति है, तो अपने यादृच्छिक आधार को 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
12

दिए गए उपयोग के मामले के लिए (यदि कोई दोहराना ठीक नहीं है) तो मैं कहूंगा कि यह अभी भी सबसे अच्छा समाधान है।
अनुराग उनियाल

3
उदाहरणों में से एक में एक दोहराव है, इसलिए मुझे संदेह है कि वह दोहराता देख रहा है।
मार्क बायर्स

5
यदि random.sample वर्ण पुन: उपयोग को रोकता है, तो वर्ण सेट का आकार गुणा करना कई पुनरावृत्तियों को संभव बनाता है , लेकिन वे अभी भी कम संभावना रखते हैं फिर वे एक शुद्ध यादृच्छिक विकल्प में हैं। यदि हम लंबाई 6 की एक स्ट्रिंग के लिए जाते हैं, और हम 'X' को पहले चरित्र के रूप में चुनते हैं, तो उदाहरण के लिए, दूसरे वर्ण के लिए 'X' प्राप्त करने की बाधाएं 'X' प्राप्त करने की बाधाओं के समान हैं। पहला चरित्र। रैंडम.सम्प्लिमेंट कार्यान्वयन में, किसी भी बाद के चरित्र के रूप में 'एक्स' प्राप्त करने की संभावना केवल 5/6 होती है और इसे पहले चरित्र के रूप में प्राप्त करने की संभावना होती है।
पीसीयूरी

1
जैसे ही आप उत्पन्न स्ट्रिंग से आगे बढ़ते हैं, किसी विशेष वर्ण को दोहराया जाने की संभावना कम हो जाती है। 26 अपरकेस अक्षर प्लस 6 अंकों से 6 वर्णों की एक स्ट्रिंग उत्पन्न करना, प्रत्येक वर्ण को स्वतंत्र रूप से चुनना, कोई भी विशेष स्ट्रिंग आवृत्ति 1 / (36 ^ 6) के साथ होती है। 'FU3WYE' और 'XXXXXX' जनरेट करने का मौका एक ही है। नमूना कार्यान्वयन में, 'XXXXXX' उत्पन्न करने का मौका है (1 / (36 ^ 6)) * ((6/6) * (5/6) * (4/6) * (3/6) * (2) / 6) * (1/6) यादृच्छिक के गैर-प्रतिस्थापन सुविधा के कारण। नमूना। नमूना कार्यान्वयन में 'XXXXXX' की संभावना 324 गुना कम है।
पीसीयूरी

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

lowercase_str एक यादृच्छिक मान है 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str है 'CEA8B32E00934AAEA8C005A35D85A5C0'


2
uppercase_str[:N+1]
यजो

@ याओ हां हम स्लाइसिंग का उपयोग कर सीमित कर सकते हैं
सवद केपी

2
@Yajo: नहीं, आप हेक्स मान का टुकड़ा नहीं करना चाहते हैं। आप अपरकेस अक्षरों और अंकों के पूर्ण अनुक्रम की तुलना में एन्ट्रापी को हटा देते हैं। संभवतः बेस 32-एनकोड के बजाय मान (थोड़ा कम एन्ट्रापी, 36 ** एन से 32 ** एन तक, अभी भी 16 ** एन से बेहतर है)।
मार्टिन पीटर्स

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उपरोक्त किसी भी समाधान की तुलना में डेवलपर-समय में तेज़ है। इग्नासियो का समाधान सबसे तेज़ चलने वाला समय है और पायथन स्टैंडर्ड लाइब्रेरी का उपयोग करके सही उत्तर है। लेकिन आप शायद ही कभी उस रूप में इसका इस्तेमाल करेंगे। आप SystemRandom (या अगर उपलब्ध नहीं है तो कमबैक) का उपयोग करना चाहते हैं, सुनिश्चित करें कि आवश्यक वर्ण सेटों का प्रतिनिधित्व किया गया है, यूनिकोड (या नहीं) का उपयोग करें, सुनिश्चित करें कि क्रमिक इनवॉइस एक अद्वितीय स्ट्रिंग का उत्पादन करें, स्ट्रिंग मॉड्यूल मॉड्यूल वर्गों में से एक के सबसेट का उपयोग करें। आदि सभी को प्रदान किए गए उत्तरों की तुलना में बहुत अधिक कोड की आवश्यकता होती है। एक समाधान के सामान्यीकरण के विभिन्न प्रयासों में ऐसी सीमाएँ हैं जो सरल सरल भाषा का उपयोग करके अधिक संक्षिप्तता और अभिव्यंजक शक्ति के साथ हल करती हैं।

यह PyPI पर है:

pip install StringGenerator

प्रकटीकरण: मैं स्ट्रजेन मॉड्यूल का लेखक हूं।


12

यदि आप इसे मॉड्यूल के बजाय क्रिप्टोग्राफिक रूप से सुरक्षित करने की आवश्यकता होती है, तो Python 3.6 से आपको secretsमॉड्यूल का उपयोग करना चाहिए (अन्यथा यह उत्तर @Ignacio Vazquez-Abrams के समान है):random

from secrets import choice
import string

''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])

एक अतिरिक्त नोट: str.joinएक जेनरेटर-अभिव्यक्ति का उपयोग करने की तुलना में एक सूची-समझ तेज़ है !


10

एक और स्टैक ओवरफ्लो उत्तर के आधार पर, एक यादृच्छिक स्ट्रिंग और एक यादृच्छिक हेक्साडेसिमल संख्या बनाने के लिए सबसे हल्का तरीका , स्वीकृत उत्तर की तुलना में बेहतर संस्करण होगा:

('%06x' % random.randrange(16**6)).upper()

काफी तेज।


1
यह अच्छा है, हालांकि यह केवल 'एएफ' का उपयोग करेगा और 'ए-जेड' का नहीं। इसके अलावा, जब पैरामीरीज़ कोड थोड़ा कम अच्छा हो जाता है N
थॉमस अहले

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छद्म यादृच्छिक कैसे नहीं है? यह संख्याओं को उत्पन्न करने के लिए एक बेहतर एल्गोरिदम का उपयोग कर सकता है जो अधिक यादृच्छिक हैं, लेकिन यह अभी भी छद्म यादृच्छिक है।
15

@ टायलो, मैं /dev/randomऔर के बीच के अंतर से अवगत हूं /dev/urandom। समस्या यह है कि /dev/randomब्लॉक जब पर्याप्त एन्ट्रापी नहीं है जो इसकी उपयोगिता को सीमित करता है। एक के लिए एक बार पैड /dev/urandom काफी अच्छा नहीं है, लेकिन मुझे लगता है कि यह छद्म यादृच्छिक यहाँ की तुलना में बेहतर है।
जॉन ला रूय

1
मैं कहूँगा कि दोनों /dev/randomऔर /dev/urandomछद्म यादृच्छिक है, लेकिन यह अपनी परिभाषा पर निर्भर हो सकता है।
टिलो

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
मैं इसे वोट नहीं करूंगा, लेकिन मुझे लगता है कि यह इतने आसान काम के लिए बहुत जटिल है। वापसी की अभिव्यक्ति एक राक्षस है। सरल जटिल से बेहतर है।
कार्ल स्मिथ

12
@CarlSmith, सच है कि मेरा समाधान कार्य के लिए थोड़ा अधिक लगता है, लेकिन मैं अन्य सरल समाधानों से अवगत था, और एक अच्छे उत्तर के लिए एक वैकल्पिक मार्ग खोजने की कामना करता था। स्वतंत्रता के बिना, रचनात्मकता खतरे में है, इस प्रकार मैंने आगे बढ़कर इसे पोस्ट किया।
nemesisfixx

7

यह विधि रैंडम.चॉइस () विधि इग्नासियो पोस्ट की तुलना में थोड़ी तेज है, और थोड़ी अधिक कष्टप्रद है।

यह छद्म यादृच्छिक एल्गोरिदम की प्रकृति का लाभ उठाता है, और बिटवाइज़ पर बैंकों और प्रत्येक चरित्र के लिए एक नया यादृच्छिक संख्या उत्पन्न करने की तुलना में तेज़ होता है।

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

... एक जेनरेटर बनाएँ जो एक बार में ५.३१ पर ५ बिट संख्या निकालता है, जब तक कोई नहीं बचा

... () सही बिट के साथ एक यादृच्छिक संख्या पर जनरेटर के परिणाम में शामिल हों

32-वर्ण स्ट्रिंग्स के लिए टाइमिट के साथ, समय था:

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

... लेकिन 64 चरित्र तार के लिए, रेंडबिट खो देता है;)

मैं शायद उत्पादन संहिता में इस दृष्टिकोण का उपयोग कभी नहीं करूंगा जब तक कि मैं वास्तव में अपने सहकर्मियों को नापसंद नहीं करता।

संपादित करें: प्रश्न (अपरकेस और अंक) के अनुरूप अपडेट किया गया है, और% और // के बजाय बिटवाइज़ ऑपरेटरों और >> का उपयोग करें


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
क्यों मैं अजगर यादृच्छिक के बजाय संख्यात्मक यादृच्छिक का उपयोग करना चाहिए?
पाक्स्र ०

क्योंकि यह प्रतिस्थापन के साथ लंबाई, चर संभावना और चयन जैसे तर्कों में अधिक विकल्प देता है।
मुदित जैन

5

कभी-कभी 0 (शून्य) और ओ (अक्षर ओ) भ्रमित हो सकते हैं। इसलिए मैं उपयोग करता हूं

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

यह एक अनिश्चित [अनंत] पुनरावृत्ति उत्पन्न करता है, यादृच्छिक अनुक्रमों में शामिल हो जाता है, पहले देने वाले पूल से यादृच्छिक रूप से चयनित प्रतीक का अनिश्चितकालीन क्रम उत्पन्न करता है, फिर इस क्रम को लंबाई वाले हिस्सों में तोड़ता है जो तब शामिल हो जाता है, इसे किसी भी अनुक्रम के साथ काम करना चाहिए: गेटिटेम का समर्थन करता है डिफ़ॉल्ट रूप से, यह केवल अल्फा न्यूमेरिक अक्षरों का एक यादृच्छिक अनुक्रम उत्पन्न करता है, हालांकि आप आसानी से अन्य चीजों को उत्पन्न करने के लिए संशोधित कर सकते हैं:

उदाहरण के लिए अंक के यादृच्छिक tuples उत्पन्न करने के लिए:

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

यदि आप मक्खी पर अनुक्रम उत्पन्न करना चाहते हैं तो बस पहचान में शामिल हों।

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

(२) यदि आप बाद में अपनी कुंजी में लोअरकेस अक्षर शामिल करना चाहते हैं, तो यह भी काम करेगा:

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

यह अनुराग उनियाल की प्रतिक्रिया और कुछ ऐसा है जिसे मैं खुद पर काम कर रहा था।

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 += random.choice(chars)
प्रातः

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
यद्यपि यह कोड प्रश्न का उत्तर दे सकता है, क्यों और / या कैसे का उत्तर देता है के संबंध में अतिरिक्त संदर्भ प्रदान करने से इसके दीर्घकालिक मूल्य में काफी सुधार होगा। कृपया कुछ स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें।
टोबी स्पाइट

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

यहां स्ट्रिंग की लंबाई को लूप के लिए बदला जा सकता है यानी i in रेंज (1, लंबाई) के लिए यह सरल एल्गोरिथ्म है जिसे समझना आसान है। यह सूची का उपयोग करता है ताकि आप ऐसे पात्रों को त्याग सकें जिनकी आपको आवश्यकता नहीं है।


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

मैं लगभग सभी उत्तरों के बावजूद जा चुका हूं लेकिन उनमें से कोई भी आसान नहीं है। मैं आपको सुझाव देना चाहूंगा कि आप पासजेन लाइब्रेरी को आजमाएं, जिसका इस्तेमाल आमतौर पर रैंडम पासवर्ड बनाने के लिए किया जाता है।

आप अपनी पसंद की लंबाई, विराम चिह्न, अंक, अक्षर और मामले के यादृच्छिक तार उत्पन्न कर सकते हैं

यहाँ आपके मामले के लिए कोड है:

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

0

यादृच्छिक 16-बाइट आईडी युक्त अक्षरों, अंकों, '_' और '-' उत्पन्न करें

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


-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 को बदलें, वर्णमाला को केवल अल्फा न्यूमेरिक या न्यूमेरिक केवल या अजीब वर्ण या जो भी आप चाहते हैं, करने के लिए अलग-अलग करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.