Zufallszahlen (Pseudo Random Numbers) mit Bordmitteln erzeugen
Veröffentlicht von Thomas Fahle am (Permalink)
Zufallszahlen erzeugen mit Bordmitteln
Perl stellt die Funktion rand(x), welche eine Zufallszahl zurück liefert, die größer oder gleich 0 und kleiner als x ist, zur Verfügung.
Beispiel: Zufallszahl zwischen 0 und 9,99
#!/usr/bin/perl use warnings; use strict; # Ganzzahlige Zufallszahl zwischen 0 und 9,99 my $zufallszahl = rand(10); print "Zufallszahl: $zufallszahl\n";
Das Programm erzeugt folgende Ausgabe:
Zufallszahl: 5.26864530825154
Ganzahlige Zufallszahlen erhalten Sie durch Kombination von int() und rand(x). Falls Sie eine Zufallszahl im Bereich 1 bis einschließlich x benötigen, addieren Sie einfach 1 zur Zufallszahl.
Beispiel: Ganzzahlige Zufallszahlen erzeugen
#!/usr/bin/perl use warnings; use strict; # Ganzzahlige Zufallszahl zwischen 0 und 9 my $zufallszahl = int(rand(10)); print "Zufallszahl: $zufallszahl\n"; # Ganzzahlige Zufallszahl zwischen 1 und 10 $zufallszahl = int(rand(10) +1 ); print "Zufallszahl: $zufallszahl\n";
Das Programm erzeugt folgende Ausgabe:
Zufallszahl: 5 Zufallszahl: 2
Beispiel: Ein Element aus einem Array zufällig auswählen
#!/usr/bin/perl use warnings; use strict; my @Numbers = qw(0 1 2 3 4 5 6 7 8 9); my $ausgewaehlt; $ausgewaehlt = int(rand(scalar(@Numbers))); print "Auswahl: $ausgewaehlt\n";
Das Programm erzeugt folgende Ausgabe:
Auswahl: 2
Beispiel: Ziehen ohne Zurücklegen
Wenn Sie mehrere Elemente zufällig auswählen möchten, bietet sich eine for-Schleife an.
Doppelte Elemente können Sie mit redo in Kombination mit einem Hash entfernen.
Jedes gezogene Element wird in einem Hash getrackt. Falls es bereits gezogen wurde, wird die for Schleife mit redo (Mach's noch einmal) wiederholt. redo erhöht den Schleifenzähler im Gegensatz zu next nicht.
#!/usr/bin/perl use warnings; use strict; # Beispiel Ziehen ohne Zurücklegen (3 aus 16) my @Numbers = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16); my $ziehung = ''; my %bereits_gezogen = (); my $gezogen; for ( 1 .. 3 ) { $gezogen = int(rand(scalar(@Numbers))); print "Auswahl: $gezogen\n"; redo if exists $bereits_gezogen{$gezogen}; $bereits_gezogen{$gezogen}++; $ziehung .= $gezogen; } print "Ziehung: $ziehung\n";
Das Programm erzeugt folgende Ausgabe:
Auswahl: 8 Auswahl: 3 Auswahl: 8 Auswahl: 7 Ziehung: 837
Zufallszahlengenerator initialisieren mit srand()
srand() initialisiert den Zufallszahlengenerator, der von rand() verwendet wird. Diese zufällige Initialisierung dient der Erzeugung verschiedener Zufallszahlen bei jedem Aufruf Ihres Programms.
Oder andersherum betrachtet, wenn stets das selbe Seed verwendet wird, werden auch immer die selben Zufallszahlen erzeugt, d.h. wenn jemand das Seed kennt oder erraten kann, kann er auch die nachfolgenden Zufallszahlen erraten.
Zur Verdeutlichung ein einfaches Beispiel:
#!/usr/bin/perl use warnings; use strict; # Sechs Seeds erstellen my @seeds = (15 .. 20); # Dreimal "Zufallszahlen" erzeugen for ( 1 .. 3 ) { &generate_pin($_); print "\n"; } exit(0); ############################################################################### sub generate_pin { my $n = shift; my $counter = 0; my @Numbers = qw(0 1 2 3 4 5 6 7 8 9); foreach my $seed (@seeds) { ############ srand $seed; ############ ++$counter; my $pin = ''; my $x; for (1 .. 5) { $x = int(rand(scalar(@Numbers))); $pin .= $Numbers[$x]; } print "PIN Nr: $counter in Runde $n: $pin\n"; } } ###############################################################################
Ausgabe.
PIN Nr: 1 in Runde 1: 23184 PIN Nr: 2 in Runde 1: 10933 PIN Nr: 3 in Runde 1: 97673 PIN Nr: 4 in Runde 1: 84323 PIN Nr: 5 in Runde 1: 71173 PIN Nr: 6 in Runde 1: 58813 PIN Nr: 1 in Runde 2: 23184 PIN Nr: 2 in Runde 2: 10933 PIN Nr: 3 in Runde 2: 97673 PIN Nr: 4 in Runde 2: 84323 PIN Nr: 5 in Runde 2: 71173 PIN Nr: 6 in Runde 2: 58813 PIN Nr: 1 in Runde 3: 23184 PIN Nr: 2 in Runde 3: 10933 PIN Nr: 3 in Runde 3: 97673 PIN Nr: 4 in Runde 3: 84323 PIN Nr: 5 in Runde 3: 71173 PIN Nr: 6 in Runde 3: 58813
Es werden jedesmal die selben (!) Zufallszahlen erzeugt.
Rufen Sie niemals srand() auf, wenn Sie nicht genau wissen, was Sie tun.
Perl ruft srand() automatisch für Sie mit einem geeignetem Seed auf, sobald rand() verwendet wird.