Zufällige Zeichenkette
Stefan Kleeschulte
- perl
0 Calocybe0 Klaus Mock0 AlexBausW
Hi zusammen!
Ich suche eine Möglichkeit in Perl eine zufällige Zeichenkette zu erzeugen, wür die ich jedoch Länge und zulässige Zeichen festlegen kann.
Ich habe mal ein bischen im Archiv gestöbert, und habe dabei folgendes gefunden (http://www.teamone.de/selfhtml/sfarchiv/2000_4/t23286.htm#a119482):
$pword = join'', map { chr($_) } (36..128)[ eval "int(rand(128-36))," x 8 ];
Das klappt auch wunderbar, und die Länge der Zeichenkette kann ich hier ja mit dem '" x n ];´ am Ende anpassen. Aber wie kann ich bestimmen, welche Zeichen enthalten sein dürfen? Ich kann z. B. in einer URL keine Zeichenkette wie "DdcO]Zex" (wurde von o.g. Code erzeugt) gebrauchen.
Für meine URL müsste ich die zulässigen Zeichen also z. B. auf Buchstaben und Zahlen beschränken.
Hat jemand eine Idee?
CU :-)
Stefan
Moin!
$pword = join'', map { chr($_) } (36..128)[ eval "int(rand(128-36))," x 8 ];
Das klappt auch wunderbar, und die Länge der Zeichenkette kann ich hier ja mit dem '" x n ];´ am Ende anpassen. Aber wie kann ich bestimmen, welche Zeichen enthalten sein dürfen?
Die verallgemeinerte Version dieser Codezeile koennte ungefaehr so aussehen:
@ALPHABET = ('a'..'z', 'A'..'Z', '0'..'9', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+');
$PASSLENGTH = 20;
$pword = join('', map { $ALPHABET[int(rand(scalar(@ALPHABET)))] } (1..$PASSLENGTH));
print $pword;
Kann man natuerlich auch in eine Zeile zusammenfassen, aber dann ist es weniger aenderungsfreundlich. ;-)
Known issues: Sonderzeichen und Zahlen werden bei dem "Algorithmus" im Vergleich zu Buchstaben relativ selten generiert. Immerhin machen Buchstaben in obigem Alphabet 52 Zeichen aus, Zahlen und Sonderzeichen zusammen nur 22. Man moege sich ueberlegen, ob man dem mit einer Mehrfachnennung von Nicht-Buchstaben im Alphabet oder einem veraenderten Auswahlverfahren begegnen will.
So long
Hallo,
versuchs mal mit String::Random.
http://www.cpan.org/modules/by-module/String/String-Random-0.198.tar.gz
Grüße
Klaus
Hallo Stefan,
Ich habe mal ein bischen im Archiv gestöbert, und habe dabei folgendes gefunden (http://www.teamone.de/selfhtml/sfarchiv/2000_4/t23286.htm#a119482):
$pword = join'', map { chr($_) } (36..128)[ eval "int(rand(128-36))," x 8 ];
Für meine URL müsste ich die zulässigen Zeichen also z. B. auf Buchstaben und Zahlen beschränken.
Es ehrt mich, daß jemand von mir geposteten Code verwendet :-).
Da die anderen beiden ja schon Möglichkeiten genannt haben, will ich ein paar Erklärungen zu obigem Code liefern.
Das Geheimnis der Buchstaben auswahl liegt in (36..128). Aus diesem Zahlenvorrat werden durch das hinten anstehende Konstrukt aus der eckigen Klammer mit eval und int(rand()) zufällig Werte entnommen und an map() weitergereicht.
Dort werden die Zahlenwerte mit chr() in Ascii-Zeichen umgewandelt um anschließend von join() zu einem String verkettet zu werden.
Die Zahlen habe ich genommen, weil der Bereichsoperator .. damit schöner arbeitet, und der Bereich der erzeugten Zufallszahlen einfach berechnet werden kann.
Wenn Du direkt Ascii-Werte verwenden willst, kannst Du das map {..} weglassen und statt (36..128) so etwas wie ('a'..'z','A'..'Z',0-9) schreiben. Dann muss hinten allerdings rand(62) stehen, damit der Bereich der Zufallszahlen wieder stimmt.
Gruß AlexBausW
P.S.: Ich glaube statt ASCII-128 als letztes Zeichen sollte man vielleicht doch nur bis 126 (~) gehen (127 = , 128 ~ Ç ) ;-)
Hi Alex!
$pword = join'', map { chr($_) } (36..128)[ eval "int(rand(128-36))," x 8 ];
P.S.: Ich glaube statt ASCII-128 als letztes Zeichen sollte man vielleicht doch nur bis 126 (~) gehen (127 = , 128 ~ Ç ) ;-)
Naja, zumindest die 128 wird ja mit obigem Code sowieso nie ausgewaehlt... ;-)
So long
Hallo Calocybe,
$pword = join'', map { chr($_) } (36..128)[ eval "int(rand(128-36))," x 8 ];
P.S.: Ich glaube statt ASCII-128 als letztes Zeichen sollte man vielleicht doch nur bis 126 (~) gehen (127 = , 128 ~ Ç ) ;-)
Naja, zumindest die 128 wird ja mit obigem Code sowieso nie ausgewaehlt... ;-)
Hmmm, danke! Jetzt weis ich auch wieder, warum ich 128 und nicht 127 als letzten Wert genommen habe ;)
Irgendwie benutze ich wohl rand() zu selten, um zu behalten, daß Werte zwischen a und b ohne b zurückgeben werden. Vielleicht müsste ich über die Bedeutung von "zwischen" etwas philosophieren ;-)
Gruß Alex