Bash/RANDOM
Bash/RANDOM - Generierung von Zufallszahlen
Überblick
Zufallszahlen in Bash-Skripten
- Bereiche
Gründen Zufallszahlen innerhalb eines bestimmten Bereichs zu generieren
- Beispielsweise eine zufällige TCP/UDP-Portnummer zwischen 1024 und 65535 für Benutzeranwendungen generieren
- Methoden zur Generierung von Zufallszahlen
Innerhalb eines bestimmten Bereichs in Bash
- Die von uns verwendeten Bereiche sind inklusive, d. h., die Unter- und Obergrenze des Bereichs sind im Bereich enthalten
- Zufallszahlen innerhalb eines bestimmten Bereichs generieren
- Umgebungsvariable $RANDOM verwenden
- Befehle
- shuf
- awk]]
- od]]
Programmiersprachen
über die Befehlszeile verwenden, um Zahlen in einem bestimmten Bereich zu generieren
$RANDOM
- Verwendung von $RANDOM
Eine Möglichkeit, Zufallszahlen innerhalb eines Bereichs zu generieren, ist die Verwendung der integrierten Umgebungsvariablen $RANDOM. Jedes Mal, wenn wir diese Umgebungsvariable verwenden, wird eine Zufallszahl zwischen 0 und 32767 generiert:
$ echo $RANDOM $RANDOM $RANDOM
6104 25795 16292
Wir haben $RANDOM dreimal in einem einzigen echo-Befehl aufgerufen. Die generierten Zahlen waren 6104, 25795 und 16292.
Obwohl der Aufruf von $RANDOM standardmäßig eine ganze Zahl zwischen 0 und 32767 generiert, ist es möglich, eine Zufallszahl in einem bestimmten Bereich zu generieren.
Verwenden wir $RANDOM, um eine Zufallszahl zwischen 10 und 20 zu generieren, als Beispiel:
$ min=10
$ max=20
$ echo $(($RANDOM%($max-$min+1)+$min))
20
$ echo $(($RANDOM%($max-$min+1)+$min))
14
($max-$min+1) ist in unserem Beispiel 11. Daher generiert der Teil $RANDOM%($max-$min+1) des Ausdrucks eine Zufallszahl zwischen 0 und 10. % ist der Modulo-Operator in Bash. Durch Hinzufügen von $min zu $RANDOM%($max-$min+1) erhält man schließlich eine ganze Zahl zwischen 10 und 20.
shuf
- Verwendung von shuf
Eine weitere Möglichkeit, Zufallszahlen innerhalb eines bestimmten Bereichs zu generieren, ist die Verwendung des Befehls shuf:
$ shuf –i $min-$max –n 1
12
Die generierte zufällige ganze Zahl ist im obigen Beispiel 12, wobei die Werte von $min und $max wie zuvor 10 und 20 sind.
Die -i Option von shuf gibt den Eingabebereich an. Die generierten Zahlen werden zufällig aus dem angegebenen Bereich ausgewählt. Die Option -n gibt die Anzahl der Zufallszahlen an, die von shuf generiert werden müssen. In unserem Beispiel erzeugt shuf nur eine Zufallszahl, da wir -n 1 an shuf übergeben.
awk
- Verwendung von awk ==
Wir können auch awk verwenden, um Zufallszahlen in einem bestimmten Bereich zu generieren:
$ awk „BEGIN{srand(); print int(rand()*($max-$min+1))+$min}“
20
Wir generieren die Zufallszahl in der BEGIN-Regel von awk, da wir keine Eingabedatei an awk übergeben. Diese Regel wird nur einmal ausgeführt.
Wir müssen die srand()-Funktion von awk aufrufen, um den Startwert für die Zufallszahlengenerierung zu initialisieren. Wenn wir keine Argumente an srand() übergeben, verwendet awk das aktuelle Datum und die aktuelle Uhrzeit als Startwert.
Die rand()-Funktion von awk generiert eine Zufallszahl zwischen 0 und 1. Die int()-Funktion von awk gibt hingegen den ganzzahligen Teil einer reellen Zahl zurück. Daher generiert der Ausdruck int(rand()*($max-$min+1))+$min in doppelten Klammern eine Zufallszahl zwischen $min und $max.
Wir können bei der Verwendung von awk auch andere Startwerte verwenden, zum Beispiel $RANDOM:
$ awk -v seed=$RANDOM „BEGIN{srand(seed); print int(rand()*($max-$min+1))+$min}“
13
Die Option -v von awk dient dazu, einer Variablen einen Wert zuzuweisen, bevor die Ausführung von awk beginnt. Das -v seed=$RANDOM in unserem Beispiel definiert die Variable seed mit dem Wert $RANDOM. Daher initialisiert der Aufruf von srand(seed) in der BEGIN-Regel den Startwert mit dem Wert, der aus der Umgebungsvariablen $RANDOM erhalten wird.
od
- Verwendung von od
Wir können den Befehl od zusammen mit den Kernel-Zufallszahlengeneratoren verwenden, um Zufallszahlen zu erzeugen.
Verwenden wir od mit /dev/urandom:
$ od -An -N2 -d /dev/urandom
41803
Die Gerätedatei /dev/urandom ist das Kernel-Zufallszahlengerät. Es ist nicht blockierend, sodass es kontinuierlich Zufallsdaten generiert. Eine weitere Option ist die Gerätedatei /dev/random. Sie kann blockieren, wenn die Entropie erschöpft ist.
Die -An-Option von od gibt das Ergebnis ohne Offset-Informationen aus. Die -N2-Option liest zwei Bytes der Eingabe. Schließlich zeigt die -d-Option von od das Ergebnis als zweibytige vorzeichenlose Ganzzahl an.
Leider ist es nicht möglich, bei Verwendung des Befehls od einen Bereich anzugeben. Wir können jedoch od innerhalb einer unendlichen while-Schleife aufrufen, bis wir eine Zahl im gewünschten Bereich erhalten. Zu diesem Zweck verwenden wir das folgende Skript, get_random_number.sh:
#!/bin/bash
min=10
max=20
while true
do
odn=$(od -An -N1 -d /dev/urandom)
if [[ $odn -ge $min ]] && [[ $odn -le $max ]]
then
echo $odn
break
fi
done
Die while-Schleife ist eine unendliche Schleife, da die Bedingung der Schleife immer wahr ist. Wir weisen die von od erhaltene Zufallszahl der Variablen odn zu, indem wir odn=$(od -An -N1 -d /dev/urandom) verwenden. Wir lesen ein Byte aus der Eingabe, da unser Bereich zwischen 10 und 20 liegt.
Wenn die Zufallszahl innerhalb des Bereichs liegt, d. h. zwischen $min und $max, geben wir sie mit echo $odn aus. Dann verlassen wir die while-Schleife mit break. Liegt die Zufallszahl außerhalb des Bereichs, generieren wir mit od weiter Zufallszahlen.
Führen wir das Skript aus:
$ ./get_random_number.sh
17
Die erhaltene Zufallszahl ist 17 und liegt wie erwartet im Bereich zwischen 10 und 20.
Die Leistung dieser Lösung ist möglicherweise nicht gut, wenn der Bereich klein ist und die Bereichsgrenzen groß sind, z. B. im Bereich zwischen 20000 und 20050, da die Anzahl der Versuche und Fehlversuche sehr hoch ist.
Python
- Verwendung von Python
Wir können die Programmiersprache Python verwenden, um Zufallszahlen innerhalb eines bestimmten Bereichs zu generieren.
Es ist möglich, Python-Anweisungen über die Befehlszeile auszuführen, ohne Python-Skripte zu schreiben, indem man die Option -c des Befehls python verwendet:
$ python –c „import random; print(random.randint($min,$max))“
14
Die erste Anweisung in den doppelten Anführungszeichen, import random, importiert das random-Modul, einen Pseudozufallszahlengenerator für verschiedene Verteilungen.
Anschließend rufen wir die Funktion randint() des Moduls random auf. Diese Funktion erzeugt eine zufällige ganze Zahl innerhalb des durch ihren ersten und zweiten Parameter angegebenen Bereichs. Wir geben den Bereich mit den Umgebungsvariablen $min und $max an. Schließlich geben wir die von random.randint() zurückgegebene Zahl mit der Funktion print() von Python aus.
Perl
- Verwendung von Perl
Perl ist eine weitere Programmiersprache, mit der wir Zufallszahlen innerhalb eines bestimmten Bereichs generieren können.
Wie bei Python können wir Perl-Anweisungen über die Befehlszeile ausführen, ohne Perl-Skripte zu schreiben:
$ perl –e „print int(rand($max-$min+1)) + $min“
19
Die -e-Option des perl-Befehls entspricht der -c-Option von python. Damit können wir Perl-Anweisungen über die Befehlszeile ausführen.
Die rand()-Funktion in Perl gibt eine zufällige reelle Zahl zurück. Die int()-Funktion konvertiert die ihr übergebene reelle Zahl in eine ganze Zahl.
Beispielsweise gibt int(rand(10)) eine zufällige ganze Zahl zwischen 0 und 9 zurück. Daher gibt der Teil int(rand($max-$min+1)) des Ausdrucks in doppelten Klammern, der an den Befehl perl übergeben wird, eine zufällige ganze Zahl zwischen 0 und 10 zurück. Durch Hinzufügen des Werts $min ergibt sich eine Zufallszahl im Bereich zwischen 10 und 20.