विशिष्ट रेंज में यादृच्छिक संख्या उत्पन्न करें


84

एक सा गुगली करने के बाद, मैं एक विशिष्ट सीमा में शामिल एक यादृच्छिक दशमलव पूर्णांक संख्या उत्पन्न करने के लिए एक शेल कमांड का उपयोग करने का एक सरल तरीका नहीं ढूंढ सका, जो कि न्यूनतम और अधिकतम के बीच है।

मैं इसके बारे में पढ़ता हूं /dev/random, /dev/urandomऔर $RANDOM, लेकिन इनमें से कोई भी ऐसा नहीं कर सकता है जिसकी मुझे आवश्यकता है।

क्या कोई अन्य उपयोगी कमांड, या पिछले डेटा का उपयोग करने का एक तरीका है?


2
यह SO Q & A देखें: stackoverflow.com/questions/8988824/… साथ ही यह stackoverflow.com/questions/2556190/…
स्लम

संभवतः संबंधित: unix.stackexchange.com/questions/42045/random-number-needed/...
SLM

जवाबों:


45

POSIX टूलकिट में, आप उपयोग कर सकते हैं awk:

awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'

है कि का उपयोग एक स्रोत के रूप पासवर्ड या उदाहरण के लिए गुप्त डेटा उत्पन्न करने के लिए, अधिकांश के साथ के रूप में awkकार्यान्वयन, संख्या आसानी से समय है कि आदेश चलाया गया था के आधार पर अनुमान लगाया जा सकता है।

कई awkकार्यान्वयन के साथ , एक ही सेकंड के भीतर दो बार चलने वाली कमांड आम तौर पर आपको समान आउटपुट देगी।


1
+1 .. जैसा कि एक स्क्रिप्ट में आउटपुट को वेरिएबल में निर्दिष्ट करने के लिए इस्तेमाल किया जाता है (w / o एक नई लाइन वर्ण प्रस्तुत करता है और दो स्थानों के लिए शून्य पैडिंग का उपयोग करता है):x=$(awk -v min=$min_var -v max=$max_var 'BEGIN{srand(); printf("%.2d", int(min+rand()*(max-min+1)))}')
क्रिस्टोफर

यह समय पर आधारित है? चूँकि मुझे लगातार 2 रनों में समान मूल्य मिला ...
Shai Alon

@ शीलॉन वर्तमान समय में अक्सर सरंड () के लिए डिफ़ॉल्ट बीज मान के रूप में उपयोग किया जाता है, इसलिए आमतौर पर, यह समय पर आधारित होता है, स्टीफन के वाक्य को उसके उत्तर में देखें। आप प्रारंभिक बीज को यादृच्छिक संख्या में बदलकर उसके चारों ओर प्राप्त कर सकते हैं awk -v min=5 -v max=10 -v seed="$(od -An -N4 -tu4 /dev/urandom)" 'BEGIN{srand(seed+0); print int(min+rand()*(max-min+1))}'। आप $RANDOMइसके बजाय उपयोग कर सकते हैं od ... /dev/randomलेकिन तब आपका बीज मान 0 से 32767 की अपेक्षाकृत छोटी सीमा में है और इसलिए समय के साथ आपको अपने उत्पादन में ध्यान देने योग्य पुनरावृत्तियां मिलेंगी।
एड मॉर्टन

141

आप shufGNU कोरुटिल्स से कोशिश कर सकते हैं :

shuf -i 1-100 -n 1

यह बिजीबॉक्स के साथ भी काम करता है shuf
कोव

रास्पियन और GitBash में भी काम करता है।
nPcomp

30

संक्षेप में लिख देना

बीएसडी और ओएसएक्स पर आप अंतराल से (समावेशी ) एक एकल यादृच्छिक ( ) संख्या वापस करने के लिए जोत का उपयोग कर सकते हैं ।-rminmax

$ min=5
$ max=10
$ jot -r 1 $min $max

वितरण की समस्या

दुर्भाग्य से, यादृच्छिक रूप से उत्पन्न संख्याओं की श्रेणी और वितरण इस तथ्य से प्रभावित है कि आउटपुट आउटपुट प्रारूप के लिए jot दोहरे परिशुद्धता फ़्लोटिंग पॉइंट अंकगणितीय और प्रिंटफ़ (3) का उपयोग करता है, जो गोलाई और ट्रंकेशन समस्याओं का कारण बनता है। इसलिए, अंतराल minऔर maxप्रदर्शन के अनुसार कम बार उत्पन्न होता है:

$ jot -r 100000 5 10 | sort -n | uniq -c
9918  5
20176 6
20006 7
20083 8
19879 9
9938  10

OS X 10.11 (El Capitan) पर यह निश्चित किया गया प्रतीत होता है:

$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10  

तथा...

$ jot -r 1000000 1 10 | sort -n | uniq -c
100430 1
99965 2
99982 3
99796 4
100444 5
99853 6
99835 7
100397 8
99588 9
99710 10

वितरण समस्या का समाधान

ओएस एक्स के पुराने संस्करणों के लिए, सौभाग्य से कई वर्कअराउंड हैं। एक प्रिंटफ (3) पूर्णांक रूपांतरण का उपयोग करना है। एकमात्र चेतावनी यह है कि अंतराल अब अधिकतम हो गया है max+1। पूर्णांक स्वरूपण का उपयोग करके, हम पूरे अंतराल में उचित वितरण प्राप्त करते हैं:

$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10

सही समाधान

अंत में, वर्कअराउंड का उपयोग करके पासा का एक उचित रोल पाने के लिए, हमारे पास:

$ min=5
$ max_plus1=11  # 10 + 1
$ jot -w %i -r 1 $min $max_plus1

अतिरिक्त होमवर्क

Gory गणित और प्रारूपण विवरण और कई और उदाहरणों के लिए jot (1) देखें ।


15

$RANDOMचर सामान्य रूप से उत्पन्न अच्छा यादृच्छिक मूल्यों के लिए एक अच्छा तरीका नहीं है। /dev/[u]randomआवश्यकता का आउटपुट भी पहले परिवर्तित किया जाना है।

एक आसान तरीका उच्च स्तरीय भाषाओं का उपयोग करना है, जैसे कि अजगर:

5 और 10 (5 <= N <= 10) के बीच एक यादृच्छिक पूर्णांक चर उत्पन्न करने के लिए, का उपयोग करें

python -c "import random; print random.randint(5,10)"

क्रिप्टोग्राफिक एप्लिकेशन के लिए इसका उपयोग न करें।


यह उपयोगी था। बहुत बहुत धन्यवाद :) जैसा कि अक्सर हस्ताक्षरित होता है, यूनिक्स-> सोलारिस 10 के साथ काम किया है जीएनयू के बर्तन डिफ़ॉल्ट रूप से एकीकृत नहीं होते हैं। हालांकि यह काम किया।
प्रवचन

11

आप के माध्यम से यादृच्छिक संख्या प्राप्त कर सकते हैं urandom

head -200 /dev/urandom | cksum

आउटपुट:

3310670062 52870

उपरोक्त संख्या के एक भाग को पुनः प्राप्त करने के लिए।

head -200 /dev/urandom | cksum | cut -f1 -d " "

फिर आउटपुट है

3310670062


head -200(या इसके POSIX समतुल्य head -n 100) की पहली 200 लाइनें लौटाता है /dev/urandom/dev/urandomएक टेक्स्ट फ़ाइल नहीं है, यह कमांड 200 बाइट्स (सभी 0x0a वाले, LF ASCII में) से अनंत तक वापस आ सकती है (यदि 0x बाइट कभी भी वापस नहीं होती है) लेकिन 45k और 55k के बीच मान सबसे अधिक होने की संभावना है। cksum एक 32 बिट नंबर देता है, इसलिए यह 4 से अधिक बाइट्स प्राप्त करने के लिए व्यर्थ है /dev/urandom
स्टीफन चेजलस

7

5 और 10 (दोनों सहित) के बीच एक यादृच्छिक पूर्णांक चर उत्पन्न करने के लिए, का उपयोग करें

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))

% एक modulo ऑपरेटर के रूप में काम करता है।

यादृच्छिक चर $RANDOMको किसी विशिष्ट श्रेणी में बदलने के लिए शायद बेहतर तरीके हैं । क्रिप्टोग्राफ़िक अनुप्रयोगों के लिए या वास्तविक, समान-वितरित यादृच्छिक चर (जैसे सिमुलेशन के लिए) की आवश्यकता के लिए इसका उपयोग न करें।


3
कई शेल कार्यान्वयनों में जिनके पास $ RANDOM है (विशेष रूप से पुराने वाले, विशेष रूप से बैश), यह बहुत यादृच्छिक नहीं है। अधिकांश गोले में, संख्या 0 और 65535 के बीच होती है, इसलिए किसी भी सीमा जिसकी चौड़ाई दो की शक्ति नहीं है, में प्रायिकता वितरण विसंगति होगी। (इस मामले में, संख्या 5 से 8 में 10923/65536 की संभावना होगी, जबकि 9 और 10 में 10922/65536 की संभावना होगी)। व्यापक सीमा, बड़ी विसंगति।
स्टीफन चेजलस

क्षमा करें, यह 32767 नहीं 65535 है, इसलिए ऊपर की गणना गलत है (और यह वास्तव में बदतर है)।
स्टीफन चेजलस


5

# echo $(( $RANDOM % 256 )) आधुनिक * श बोलियों में 0-255 के बीच एक "यादृच्छिक" संख्या उत्पन्न करेगा।


2 साल पहले के इस अन्य उत्तर के समान दिखता है ।
जेफ स्कालर

1
यह कबूतर की समस्या (टीएल; डीआर: कुछ परिणाम दूसरों की तुलना में अधिक होने की संभावना है) के अधीन है , यदि 256 के बजाय, आप एक मान का उपयोग करते हैं जो 32768 को समान रूप से विभाजित नहीं करता है।
तून81

4

शायद UUID(लिनक्स पर) यादृच्छिक संख्या को पुनः प्राप्त करने के लिए इस्तेमाल किया जा सकता है

$ cat /proc/sys/kernel/random/uuid
cdd52826-327d-4355-9737-895f58ad11b4

के बीच 70और यादृच्छिक संख्या प्राप्त करने के लिए100

POSIXLY_CORRECT=1 awk -F - '{print(("0x"$1) % 30 + 70)}
   ' /proc/sys/kernel/random/uuid

3
cat /dev/urandom | tr -dc 'a-fA-F0-9' | fold -w 8 | head -n 1

यह एक 8 अंक लंबी हेक्साडेसिमल संख्या उत्पन्न करेगा।


1

पूरी तरह से बैश रहने और $ RANDOM चर का उपयोग करने के लिए लेकिन असमान वितरण से बचें:

#!/bin/bash
range=10 
floor=20

if [ $range -gt 32768 ]; then
echo 'range outside of what $RANDOM can provide.' >&2
exit 1 # exit before entering infinite loop
fi 

max_RANDOM=$(( 2**15/$range*$range ))
r=$RANDOM
until [ $r -lt $max_RANDOM ]; do
r=$RANDOM
done
echo $(( r % $range + $floor ))

यह उदाहरण 20 से 29 के माध्यम से यादृच्छिक संख्या प्रदान करेगा।


$rएक [: -lt: unary operator expectedत्रुटि से बचने के लिए 65535 या अन्य उच्च मूल्य पर आरंभीकृत किया जाना चाहिए ।
लॉरेंस

पाश परीक्षण से पहले $ r आरंभीकरण को ठीक किया। धन्यवाद @LawrenceC!
अंगेल

0

वितरण अच्छा है:

के लिए ((i = 1; मैं <= 100000; i ++)) प्रतिध्वनि $ करते हैं ((रैंडम% (20 - 10 + 1) + 10)); हो गया | सॉर्ट-एन | uniq -c

गणना मूल्य

9183 10

9109 11

8915 12

9037 13

9100 14

9138 15

9125 16

9261 17

9088 18

8996 19

9048 20

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