Hoe genereer je een willekeurig getal binnen een bereik in Bash?
Antwoord 1, autoriteit 100%
Gebruik $RANDOM
. Het is vaak handig in combinatie met eenvoudige shell-rekenkunde. Om bijvoorbeeld een willekeurig getal tussen 1 en 10 te genereren (inclusief):
$ echo $((1 + $RANDOM % 10))
3
De eigenlijke generator zit in variables.c
, de functie brand()
. Oudere versieswaren een eenvoudige lineaire generator. Versie 4.0 van bash
gebruikt een generator met een citaat naar een paper uit 1985, wat vermoedelijk betekent dat het een behoorlijke bron van pseudo-willekeurige getallen is. Ik zou het niet gebruiken voor een simulatie (en zeker niet voor crypto), maar het is waarschijnlijk voldoende voor elementaire scripttaken.
Als je iets doet waarvoor serieuze willekeurige getallen nodig zijn, kun je /dev/random
of /dev/urandom
gebruiken als ze beschikbaar zijn:
$ dd if=/dev/urandom count=4 bs=1 | od -t d
Antwoord 2, autoriteit 24%
Zie $RANDOM
:
$RANDOM
is een interne Bash-functie
(geen constante) die a . retourneert
pseudowillekeurig geheel getal in het bereik
0 – 32767. Het mag niet worden gebruikt om
genereer een coderingssleutel.
Antwoord 3, autoriteit 18%
Je kunt ook shuf
(beschikbaar in coreutils).
shuf -i 1-100000 -n 1
Antwoord 4, autoriteit 10%
Probeer dit vanuit je shell:
$ od -A n -t d -N 1 /dev/urandom
Hier specificeert -t d
dat het uitvoerformaat moet worden ondertekend decimaal; -N 1
zegt één byte te lezen van /dev/urandom
.
Antwoord 5, autoriteit 7%
je kunt ook een willekeurig nummer krijgen van awk
awk 'BEGIN {
# seed
srand()
for (i=1;i<=1000;i++){
print int(1 + rand() * 100)
}
}'
Antwoord 6, autoriteit 5%
Er is $RANDOM.
Ik weet niet precies hoe het werkt. Maar het werkt.
Om te testen, kunt u het volgende doen:
echo $RANDOM
Antwoord 7, autoriteit 5%
Ik vind deze truc leuk:
echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99
…
Antwoord 8, autoriteit 3%
Willekeurig getal tussen 0 en 9, inclusief.
echo $((RANDOM%10))
Antwoord 9, autoriteit 2%
bash 5.1introduceert een nieuwe variabele, SRANDOM
, die zijn willekeurige gegevens krijgt van de entropie-engine van het systeem en is dus niet lineair en kan niet opnieuw worden geplaatst om een identieke willekeurige reeks te krijgen. Deze variabele kan worden gebruikt als vervanging voor RANDOM
voor het genereren van meer willekeurigegetallen.
$ echo $((1 + SRANDOM % 10))
4
Antwoord 10
Als je een linux-systeem gebruikt, kun je een willekeurig getal halen uit /dev/ willekeurig of/dev/urandom. Wees voorzichtig /dev/random zal blokkeren als er niet genoeg willekeurige getallen beschikbaar zijn. Als je snelheid boven willekeur nodig hebt, gebruik dan /dev/urandom.
Deze “bestanden” worden gevuld met willekeurige getallen die door het besturingssysteem worden gegenereerd. Het hangt af van de implementatie van /dev/random op uw systeem of u echte of pseudo-willekeurige getallen krijgt. Echte willekeurige getallen worden gegenereerd met behulp van ruis verzameld van apparaatstuurprogramma’s zoals muis, harde schijf, netwerk.
Je kunt willekeurige getallen uit het bestand halen met dd
Antwoord 11
Ik heb een paar van deze ideeën genomen en een functie gemaakt die snel zou moeten werken als er veel willekeurige getallen nodig zijn.
bellen naar od
is duur als je veel willekeurige nummers nodig hebt. In plaats daarvan noem ik het één keer en sla ik 1024 willekeurige getallen op uit /dev/urandom. Wanneer rand
wordt aangeroepen, wordt het laatste willekeurige getal geretourneerd en geschaald. Het wordt dan uit de cache verwijderd. Als de cache leeg is, worden nog eens 1024 willekeurige getallen gelezen.
Voorbeeld:
rand 10; echo $RET
Retourneert een willekeurig getal in RET tussen 0 en 9.
declare -ia RANDCACHE
declare -i RET RAWRAND=$(( (1<<32)-1 ))
function rand(){ # pick a random number from 0 to N-1. Max N is 2^32
local -i N=$1
[[ ${#RANDCACHE[*]} -eq 0 ]] && { RANDCACHE=( $(od -An -tu4 -N1024 /dev/urandom) ); } # refill cache
RET=$(( (RANDCACHE[-1]*N+1)/RAWRAND )) # pull last random number and scale
unset RANDCACHE[${#RANDCACHE[*]}-1] # pop read random number
};
# test by generating a lot of random numbers, then effectively place them in bins and count how many are in each bin.
declare -i c; declare -ia BIN
for (( c=0; c<100000; c++ )); do
rand 10
BIN[RET]+=1 # add to bin to check distribution
done
for (( c=0; c<10; c++ )); do
printf "%d %d\n" $c ${BIN[c]}
done
UPDATE: dat werkt niet zo goed voor alle N. Het verspilt ook willekeurige bits als het wordt gebruikt met kleine N. Merk op dat (in dit geval) een 32-bits willekeurig getal voldoende entropie heeft voor 9 willekeurige getallen tussen 0 en 9 ( 10*9=1.000.000.000 <= 2*32) we kunnen meerdere willekeurige getallen extraheren uit elke 32 willekeurige bronwaarde.
#!/bin/bash
declare -ia RCACHE
declare -i RET # return value
declare -i ENT=2 # keep track of unused entropy as 2^(entropy)
declare -i RND=RANDOM%ENT # a store for unused entropy - start with 1 bit
declare -i BYTES=4 # size of unsigned random bytes returned by od
declare -i BITS=8*BYTES # size of random data returned by od in bits
declare -i CACHE=16 # number of random numbers to cache
declare -i MAX=2**BITS # quantum of entropy per cached random number
declare -i c
function rand(){ # pick a random number from 0 to 2^BITS-1
[[ ${#RCACHE[*]} -eq 0 ]] && { RCACHE=( $(od -An -tu$BYTES -N$CACHE /dev/urandom) ); } # refill cache - could use /dev/random if CACHE is small
RET=${RCACHE[-1]} # pull last random number and scale
unset RCACHE[${#RCACHE[*]}-1] # pop read random number
};
function randBetween(){
local -i N=$1
[[ ENT -lt N ]] && { # not enough entropy to supply ln(N)/ln(2) bits
rand; RND=RET # get more random bits
ENT=MAX # reset entropy
}
RET=RND%N # random number to return
RND=RND/N # remaining randomness
ENT=ENT/N # remaining entropy
};
declare -ia BIN
for (( c=0; c<100000; c++ )); do
randBetween 10
BIN[RET]+=1
done
for c in ${BIN[*]}; do
echo $c
done
Antwoord 12
Lezen uit /dev/random of /dev/urandom karakter speciale bestanden is de juiste keuze.
Deze apparaten retourneren echt willekeurige getallen wanneer ze worden gelezen en zijn ontworpen
om toepassingssoftware te helpen bij het kiezen van veilige sleutels voor codering. Zo een
willekeurige getallen worden geëxtraheerd uit een entropiepool die wordt bijgedragen
door verschillende willekeurige gebeurtenissen. {LDD3, Jonathan Corbet, Alessandro
Rubini en Greg Kroah-Hartman]
Deze twee bestanden zijn in het bijzonder een interface voor randomisatie van de kernel
void get_random_bytes_arch(void* buf, int nbytes)
die echt willekeurige bytes uit hardware haalt als een dergelijke functie door hardware is geïmplementeerd (meestal), of uit een entropiepool (bestaande uit timings tussen gebeurtenissen zoals muis- en toetsenbordonderbrekingen en andere onderbrekingen die zijn geregistreerd bij SA_SAMPLE_RANDOM).
dd if=/dev/urandom count=4 bs=1 | od -t d
Dit werkt, maar schrijft onnodige uitvoer van dd
naar stdout. De onderstaande opdracht geeft alleen het gehele getal dat ik nodig heb. Ik kan zelfs een gespecificeerd aantal willekeurige bits krijgen als ik nodig heb door het bitmasker aan te passen dat wordt gegeven aan rekenkundige uitbreiding:
me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))
Antwoord 13
Genereer een willekeurig getal in het bereik van 0 tot n (ondertekend 16-bits geheel getal). Resultaat ingesteld in $RAND variabele. Bijvoorbeeld:
#!/bin/bash
random()
{
local range=${1:-1}
RAND=`od -t uI -N 4 /dev/urandom | awk '{print $2}'`
let "RAND=$RAND%($range+1)"
}
n=10
while [ $(( n -=1 )) -ge "0" ]; do
random 500
echo "$RAND"
done
Antwoord 14
Hoe zit het met:
perl -e 'print int rand 10, "\n"; '
Antwoord 15
Misschien ben ik een beetje te laat, maar hoe zit het met het gebruik van jot
om een willekeurig getal binnen een bereik in Bash te genereren?
jot -r -p 3 1 0 1
Dit genereert een willekeurig (-r
) getal met een precisie van 3 decimalen (-p
). In dit specifieke geval krijg je één getal tussen 0 en 1 (1 0 1
). U kunt ook opeenvolgende gegevens afdrukken. De bron van het willekeurige getal, volgens de handleiding, is:
Willekeurige getallen worden verkregen via arc4random(3) als er geen seed is opgegeven, en via
random(3) wanneer een seed wordt gegeven.
Antwoord 16
Gebaseerd op de geweldige antwoorden van @Nelson, @Barun en @Robert, is hier een Bash-script dat willekeurige getallen genereert.
- Kan het gewenste aantal cijfers genereren.
- elk cijfer wordt afzonderlijk gegenereerd door
/dev/urandom
, wat veel beteris dan de ingebouwde$RANDOM
van Bash
#!/usr/bin/env bash
digits=10
rand=$(od -A n -t d -N 2 /dev/urandom |tr -d ' ')
num=$((rand % 10))
while [ ${#num} -lt $digits ]; do
rand=$(od -A n -t d -N 1 /dev/urandom |tr -d ' ')
num="${num}$((rand % 10))"
done
echo $num
Antwoord 17
Ik heb hier verschillende artikelen over geschreven.
- https://linuxconfig.org/generating-random-numbers -in-bash-met-voorbeelden
- https://linuxconfig.org/random-entropy-in-bash
- https://www.cloudsavvyit.com/7572/how-to-generate-better-random-numbers-at-the-bash-command-line/
$ RANDOM=$(date +%s%N | cut -b10-19)
$ echo $(( $RANDOM % 113 + 13 ))
Het bovenstaande geeft een getal tussen 13 en 113, met een redelijke willekeurige entropie.
Antwoord 18
Willekeurige vertakking van een programma of ja/nee; 1/0; waar/onwaar uitvoer:
if [ $RANDOM -gt 16383 ]; then # 16383 = 32767/2
echo var=true/1/yes/go_hither
else
echo var=false/0/no/go_thither
fi
van als je lui bent om 16383 te onthouden:
if (( RANDOM % 2 )); then
echo "yes"
else
echo "no"
fi
Antwoord 19
Genereer een willekeurig 3-cijferig nummer
Dit is geweldig voor het maken van voorbeeldgegevens. Voorbeeld: plaats alle testgegevens in een map met de naam “test-create-volume-123”, en zap de hele map nadat uw test is voltooid. Door exact drie cijfers te genereren, heeft u geen rare sorteerproblemen.
printf '%02d\n' $((1 + RANDOM % 100))
Dit wordt kleiner, b.v. tot één cijfer:
printf '%01d\n' $((1 + RANDOM % 10))
Het schaalt op, maar slechts tot vier cijfers. Zie hierboven waarom 🙂
Antwoord 20
Wilde /dev/urandom gebruiken zonder dden od
function roll() { local modulus=${1:-6}; echo $(( 1 + 0x$(env LC_CTYPE=C tr -dc '0-9a-fA-F' < /dev/urandom | head -c5 ) % $modulus )); }
Testen
$ roll
5
$ roll 12
12
Hoe willekeurig is het?
$ (echo "count roll percentage"; i=0; while [ $i -lt 10000 ]; do roll; i=$((i+1)); done | sort | uniq -c | awk '{print $0,($1/10000*100)"%"}') | column -t
count roll percentage
1625 1 16.25%
1665 2 16.65%
1646 3 16.46%
1720 4 17.2%
1694 5 16.94%
1650 6 16.5%
Antwoord 21
Een bash-functie die perl gebruikt om een willekeurig aantal van n cijfers te genereren. Geef het aantal cijfers op of een sjabloon van n 0s.
rand() {
perl -E '$ARGV[0]||=""; $ARGV[0]=int($ARGV[0])||length($ARGV[0]); say join "", int(rand(9)+1)*($ARGV[0]?1:0), map { int(rand(10)) } (0..($ARGV[0]||0)-2)' $1
}
Gebruik:
$ rand 3
381
$ rand 000
728
Demonstratie van het aanroepen van rand n, voor n tussen 0 en 15:
$ for n in {0..15}; do printf "%02d: %s\n" $n $(rand $n); done
00: 0
01: 3
02: 98
03: 139
04: 1712
05: 49296
06: 426697
07: 2431421
08: 82727795
09: 445682186
10: 6368501779
11: 51029574113
12: 602518591108
13: 5839716875073
14: 87572173490132
15: 546889624135868
Demonstratie van het aanroepen van rand n, voor n een sjabloon van nullen tussen lengte 0 en 15
$ for n in {0..15}; do printf "%15s :%02d: %s\n" $(printf "%0${n}d" 0) $n $(rand $(printf "%0${n}d" 0)); done
0 :00: 0
0 :01: 0
00 :02: 70
000 :03: 201
0000 :04: 9751
00000 :05: 62237
000000 :06: 262860
0000000 :07: 1365194
00000000 :08: 83953419
000000000 :09: 838521776
0000000000 :10: 2355011586
00000000000 :11: 95040136057
000000000000 :12: 511889225898
0000000000000 :13: 7441263049018
00000000000000 :14: 11895209107156
000000000000000 :15: 863219624761093
Antwoord 22
Je kunt een seed gebruiken:
RANDOM=$(date +%s%N | cut -b10-19)
echo $(( $RANDOM % 100 + 1 ))