यादृच्छिक संख्या कैसे उत्पन्न करें?


23

मैं नई लाइन द्वारा अलग किए गए एक या कुछ रैंडम नंबर जेनरेट करना चाहूंगा।

यह कैसे किया जा सकता है?


1
शुद्ध विम? या, कहते हैं, का उपयोग कर :python?
मूरू

शुद्ध विम पसंद है, लेकिन अगर यह बिल्ड-इन नहीं है, तो कोई भी आसान यादगार तरीका ठीक है।
kenorb

जवाबों:


20

इसके लिए कोई अंतर्निहित सुविधा नहीं है, इसलिए आपको कुछ बाहरी उपयोग करने की आवश्यकता होगी।

UNIX शैल ( /bin/sh)

कॉलिंग:

strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15

साथ system()एक अच्छा तरीका है। आप की जगह केवल संख्या प्राप्त कर सकते हैं trके साथ grep:

strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15

आप इसका उपयोग विम में इस तरह कर सकते हैं:

:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]'  | head -c15")

संख्या 15 वह संख्या है जो आप चाहते हैं (तदनुसार समायोजित करें)। यह लिनक्स, बीएसडी, ओएसएक्स और अन्य यूनिक्स प्रणालियों पर काम करना चाहिए। यह एमएस विंडोज पर काम नहीं करेगा।

मेरी वेबलॉग पोस्ट " कमांडलाइन से पासवर्ड जेनरेट करें " देखें (वहां इसके लिए बहुत सारे बुरे समाधान हैं)।

माणिक

रूबी शायद अगली सबसे अच्छी पसंद है, क्योंकि रूबी स्क्रिप्टिंग पायथन स्क्रिप्टिंग से कुछ अधिक सामान्य लगती है। एक यादृच्छिक संख्या प्राप्त करना आसान है:

:ruby puts Random.rand(10)

या 15 नंबर पाने के लिए:

:ruby 15.times { puts Random.rand(10) }

अजगर

आप यादृच्छिक मॉड्यूल का उपयोग कर सकते हैं ; एक ही नंबर पाने के लिए:

:py import random; print(random.randint(0, 9))

या 15 नंबर:

:py import random
:py for i in range(0, 15): print(random.randint(0, 9))

यह पायथन 2 और 3 दोनों के लिए काम करना चाहिए।

विंडोज पॉवरशेल

आप Get-Random एक यादृच्छिक संख्या प्राप्त करने के लिए उपयोग कर सकते हैं :

:echo system('Get-Random')

विंडोज cmd.exe

विंडोज 7 और बाद में PowerShell के साथ जहाज करना चाहिए, लेकिन यदि आप अधिकतम संगतता चाहते हैं तो आप उपयोग कर सकते हैं cmd.exe। इसका एक विशेष चर है %RANDOM%:

:echo system('@echo %RANDOM%')

नोट: यह बहुत यादृच्छिक नहीं है! , यह समय का उपयोग करता है (!)


ध्यान दें कि आपको रूबी या पायथन बाइंडिंग का उपयोग करने की आवश्यकता नहीं है रूबी या पायथन समाधान का उपयोग करें; आप एक अलग स्क्रिप्ट भी बना सकते हैं और उन्हें कॉल कर सकते हैं system("python -c '...'")(इसके लिए आवश्यक है कि रूबी / अजगर स्थापित हो, जाहिर है।


इसके बजाय tr -d '[:space:]', शायद tr -cd '[:digit:]'grep फ़िल्टर के लिए?
मूरू

@ muru मुझे यकीन नहीं है कि OSX पर काम करेगा, यही वजह है कि मैंने इसका इस्तेमाल नहीं किया ... आप भी इस तरह से एक newline से अलग संख्या प्राप्त करते हैं, जैसे ओपी ने पूछा ....
मार्टिन टूरनोइज

अगर ऐसा है तो .... GNU BSD को मात देता है। : पी
मूरू

रैंडम नंबरों को इनपुट करने के लिए शेल (सिस्टम) का भी उपयोग किया जा सकता है, यानी :r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom3 रैंडम साइन किए गए पूर्णांकों को उत्पन्न करेगा।
एचएएल 9001

1
@kenorb यह सही ढंग से हस्ताक्षरित 3 हस्ताक्षरित यादृच्छिक पूर्णांक के लिए शेल का उपयोग करेगा::r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
एचएएल 9001

12

यहाँ एक शुद्ध vimcript समाधान है। मैंने इसे नहीं बनाया, इसे चार्ल्स ई। कैंपबेल ने विकसित किया था। आप यहां उनके कोड के साथ जीथब रेपो पा सकते हैं ।


एल्गोरिथ्म विम स्टार्टअप पर उत्पन्न 3 बीजों का उपयोग करता है और बीजों पर लागू गणना और क्रमांकन के आधार पर एक छद्म यादृच्छिक संख्या उत्पन्न करता है:

" Randomization Variables
" with a little extra randomized start from localtime()
let g:rndm_m1 = 32007779 + (localtime()%100 - 50)
let g:rndm_m2 = 23717810 + (localtime()/86400)%100
let g:rndm_m3 = 52636370 + (localtime()/3600)%100

चर क्षेत्र को वैश्विक घोषित किया गया है क्योंकि वे जनरेटर फ़ंक्शन द्वारा उपयोग किए जाते हैं लेकिन इसे स्क्रिप्ट तक सीमित किया जा सकता है ( s:)

और यहाँ जनरेटर फ़ंक्शन है:

function! Rndm()
    let m4= g:rndm_m1 + g:rndm_m2 + g:rndm_m3
    if( g:rndm_m2 < 50000000 )
        let m4= m4 + 1357
    endif
    if( m4 >= 100000000 )
        let m4= m4 - 100000000
        if( m4 >= 100000000 )
            let m4= m4 - 100000000
        endif
    endif
    let g:rndm_m1 = g:rndm_m2
    let g:rndm_m2 = g:rndm_m3
    let g:rndm_m3 = m4
    return g:rndm_m3
endfun

रेपो में निम्नलिखित कार्य शामिल हैं:

  • बीजों के एक "रैंडमिश" आरंभीकरण;
  • पाठ फ़ाइल से कुछ उपयोगकर्ता-परिभाषित बीज पढ़ने का एक तरीका;
  • एक छद्म यादृच्छिक जनरेटर
  • कई यादृच्छिक कार्य:
    • एक फ़ंक्शन जो एक सीमा के भीतर एक यादृच्छिक संख्या उत्पन्न करता है
    • एक पासा रोलिंग समारोह
    • अनुक्रमिक पूर्णांकों की सूची को बेतरतीब ढंग से स्वैप करने के लिए एक फ़ंक्शन

यहां एक त्वरित परीक्षण है जो मैंने जनरेटर का परीक्षण करने के लिए लिखा था: मैंने 0 और 9 के बीच 1000000 नंबर उत्पन्न किए और यहां प्रत्येक संख्या की घटनाओं की संख्या गिना।

0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867

जैसा कि आप देख सकते हैं कि पीढ़ी अच्छी तरह से वितरित की जा रही है। मुझे पता है कि यह एक यादृच्छिक जनरेटर का परीक्षण करने के लिए काफी हद तक पर्याप्त नहीं है, इसलिए यदि मेरे पास कुछ खाली समय है तो मैं कुछ अतिरिक्त विश्लेषण करने की कोशिश करूंगा।


7

यह एक तरीका है जो विम-रैंडमटेग प्लगइन में पाया जाता है , जो पढ़ने पर आधारित होता है ... वर्तमान समय के माइक्रोसेकंड, जब आप बस कुछ नंबर चाहते हैं , तो आप बेतरतीब गुणवत्ता के बारे में ज्यादा परवाह नहीं करते हैं, या सुरक्षा चिंताएं आदि हैं:

function! s:randnum(max) abort
  return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction

4

विम देशी यादृच्छिक जनरेटर की पेशकश नहीं करता है, हालांकि अगर आपने पायथन के साथ संकलित किया है, तो निम्न विधि आपकी रेखा के अंत में एक यादृच्छिक अंक जोड़ देगी:

:py import vim, random; vim.current.line += str(random.randint(0, 9))

नोट: यह जांचने के लिए कि क्या आपका विम अजगर का समर्थन करता है, कोशिश करें: :echo has('python')(हाँ के लिए 1)।

आप शेल का भी उपयोग कर सकते हैं जो $RANDOMचर प्रदान करता है (bash / ksh / zsh के साथ काम करता है) जो एक छद्म आयामी (0-32767) देता है, उदाहरण के लिए:

:r! echo $RANDOM

या:

:put =system('echo $RANDOM')

या:

:r! od -An -td -N1 /dev/urandom

/ SUA स्थापित Windows पर, आप Cygwin / MSYS के लिए है, या उपयोग %RANDOM%चर के रूप में Carpetsmoker का सुझाव दिया।

यदि आपके पास शेल और पायथन तक पहुंच नहीं है, तो वर्कअराउंड के लिए, आप वर्तमान टाइमस्टैम्प से अंतिम कुछ अंकों का उपयोग करते हैं:

:put =reltimestr(reltime())[-2:]

नोट: यदि आप इसे अक्सर उपयोग कर रहे हैं, तो एक साधारण फ़ंक्शन लिखें जो होगा return reltimestr(reltime())[-4:]

नोट: ऊपर दिए गए तरीके केवल एक छद्म आयामी पूर्णांक लौटाते हैं जिसका उपयोग एन्क्रिप्शन कुंजी उत्पन्न करने के लिए नहीं किया जाना चाहिए।


अधिक यादृच्छिक संख्याओं को जोड़ने के लिए कृपया @:कमांड को दोबारा दोहराने के लिए दबाएं । या 10@:नई लाइनों द्वारा अलग किए गए यादृच्छिक संख्याओं के बहुत अधिक जोड़ने के लिए संख्या (जैसे ) के साथ उपसर्ग ।


सम्बंधित:


यह भी साथ काम करता है zsh, लेकिन नहीं के साथ sh, dash, fish, csh, या tcsh... आप इस्तेमाल कर सकते हैं :r! bash -c 'echo $RANDOM'...
मार्टिन Tournoij

"वर्तमान टाइमस्टैम्प से अंतिम कुछ अंक लौटाएं" -> यह यादृच्छिक नहीं है। छद्म यादृच्छिक संख्या प्राप्त करने के लिए समय का उपयोग करना लगभग हमेशा एक बुरा विचार है, यहां तक कि गैर-क्रिप्टो उद्देश्यों के लिए भी । क्या होगा अगर टाइमस्टैम्प का रिज़ॉल्यूशन सेकंड में है और आप एक सेकंड में दो बार "फ़ाइल। $ यादृच्छिक" बनाते हैं? ऊप्स! ... इसके अलावा, आप कभी भी नहीं जानते हैं कि जब कोई आपके GetRandom()फ़ंक्शन का उपयोग करने जा रहा है, जहां अच्छा चुभन मायने रखता है, तो यह बेहतर है कि इसे शुरू से ही सही से प्राप्त करें यदि संभव हो तो (और यह लगभग हमेशा संभव है!)
मार्टिन टूरनोइज

मुझे नहीं पता कि गुणवत्ता क्या $RANDOMहै, लेकिन अगर यह एक खराब PRNG है, तो यह भी एक गरीब PRNG का उपयोग करने का कारण नहीं है :-) इसके बजाय, एक बेहतर PRNG में अपग्रेड करें! जहां तक ​​मुझे पता है, /dev/urandomसभी प्लेटफार्मों bashपर उपलब्ध है जहां आमतौर पर उपलब्ध है, इसलिए मुझे इसका उपयोग नहीं करने का कोई कारण नहीं दिखता है।
मार्टिन टूरनोइज

1
मैं इसके बारे में नहीं जानता था $RANDOM। एक बहुत ही अच्छे छोटे उपकरण की तरह लगता है, और भले ही यह "गरीब आदमी आरएनजी" हो (जैसा कि @Carpetsmoker बताते हैं), यह निश्चित रूप से @ kenorb (जिसने सवाल पूछा है) की आवश्यकता को "आसानी से यादगार" कहा जाता है।
डल्कर

4

आप rand()और srand()फ़ंक्शंस का उपयोग कर सकते हैं , बशर्ते आपके विम बाइनरी में पैच 8.1.2342 शामिल हो


एक उदाहरण के रूप में, newlines द्वारा अलग किए गए 10 यादृच्छिक संख्याओं को उत्पन्न करने के लिए:

let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")

सभी 10 से 10 यादृच्छिक संख्या उत्पन्न करने के लिए अवर:

let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")

5 अक्षरों के 10 यादृच्छिक वर्णक्रमीय तार उत्पन्न करने के लिए:

let seed = srand()
echo range(10)
   \ ->map({-> range(5)
   \           ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
   \ ->join("\n")

10 यादृच्छिक शब्द उत्पन्न करने के लिए (शब्दकोश फ़ाइल से लिया गया /usr/share/dict/words):

let seed = srand()
let words = readfile('/usr/share/dict/words')
let len = len(words)
echo range(10)->map({-> g:words[rand(g:seed) % g:len]})->join("\n")

5 यादृच्छिक शब्दों के 10 क्रम उत्पन्न करने के लिए:

let seed = srand()
let words = readfile('/usr/share/dict/words')
let len = len(words)
echo range(10)
   \ ->map({-> range(5)
   \           ->map({-> g:words[rand(g:seed) % g:len]})->join()})
   \ ->join("\n")

एक यादृच्छिक UUID संस्करण 4 उत्पन्न करने के लिए:

" Based on this answer: /programming//a/38191078/9780968
let seed = srand()
let random_numbers = range(30)->map({-> rand(g:seed) % 16})
echo call('printf', ['%x%x%x%x%x%x%x%x-%x%x%x%x-4%x%x%x'] + random_numbers[:14])
 \ ..call('printf', ['-X%x%x%x-%x%x%x%x%x%x%x%x%x%x%x%x'] + random_numbers[15:])
 \   ->substitute('X', '89ab'[rand(seed) % 4], '')

यादृच्छिक रंग योजना लागू करने के लिए:

let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]

3

मुझे नहीं लगता कि Vimscript में यादृच्छिक संख्याओं के लिए एक मूल कार्य है।

उपयोग करने का एक तरीका :python(इसे किसी फ़ंक्शन में उपयोग करें, शायद, 10000 और 60 के साथ पैरामीटर द्वारा प्रतिस्थापित किया गया है):

:python <<EOF
import vim
import random

line = vim.current.window.cursor[0]
r = getattr(__builtins__, 'xrange', range) # To make it work for both Python 2 & 3
vim.current.buffer[line:line] = list(map(str, random.sample(r(10000), 60)))
EOF

विम में अजगर स्क्रिप्टिंग पर एक त्वरित परिचय के लिए अजगर के माध्यम से विम में एक बॉक्स बनाने के लिए मेरा जवाब देखें ।

चूंकि vim.current.bufferस्ट्रिंग्स की एक सूची है, हम स्ट्रिंग्स की एक सूची को उस तरह से असाइन कर सकते हैं जिस तरह से हम पायथन में करेंगे। random.sampleकेवल सबसे आसान तरीका है, जिसे मैं पायथन में यादृच्छिक पूर्णांकों की सूची प्राप्त करने के लिए सोच सकता हूं।


@Carpetsmoker random.samplePython 2 पर केवल दो तर्कों को दोहराता है, strचीजों को तार में बदलने का बिलिन फ़ंक्शन है। मुझे Py3 समकक्षों को देखने दो ( strसमान होगा, जांचना होगा xrangeऔर random.sample)।
मूरू

@Carpetsmoker aargh, टाइपो। 60 के बाद का ब्रैकेट 10000 के बाद का माना जाता है। और xrangeपायथन 3 में नहीं है क्योंकि rangeबराबर है (न तो वास्तव rangeमें Py2 के विपरीत, एक सूची का निर्माण करता है )।
मूरू

@Carpetsmoker और अंतिम अंतर यह है कि mapPy3 में एक पुन: चलने योग्य है और एक सूची नहीं है, इसलिए अंतिम पंक्ति का उपयोग होगाlist(map(str, random.sample(range(10000), 60)))
muru

ठीक है, मैंने आपके पोस्ट को कुछ (मामूली) परिवर्तनों के साथ संपादित करने के लिए लिया है, इसे पायथन 2 और 3 दोनों के साथ संगत करने के लिए ...
मार्टिन टूरनोइज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.