Generieren Sie eine zufällige Zeichenfolge mit 5 Zeichen
101
Ich möchte genau 5 zufällige Zeichenfolgen mit der geringsten Wahrscheinlichkeit erstellen, dass sie dupliziert werden. Was wäre der beste Weg, dies zu tun? Vielen Dank.
Mit Random::alphanumericString($length)können Sie Zeichenfolgen mit 0-9a-zA-Z abrufen, die aus kryptografisch sicheren Zufallsdaten stammen.
Caw
Antworten:
162
$rand = substr(md5(microtime()),rand(0,26),5);
Wäre meine beste Vermutung - es sei denn, Sie suchen auch nach Sonderzeichen:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'0123456789!@#$%^&*()');// and any other characters
shuffle($seed);// probably optional since array_is randomized; this may be redundant
$rand ='';foreach(array_rand($seed,5)as $k) $rand .= $seed[$k];
Hinweis: Inkrementell bedeutet leichter zu erraten. Wenn Sie dies als Salz- oder Verifizierungs-Token verwenden, tun Sie dies nicht. Ein Salz (jetzt) von "WCWyb" bedeutet in 5 Sekunden "WCWyg")
Das Problem bei der Verwendung ist md5()jedoch, dass Sie eine Zeichenfolge aus einem 16-Zeichen-Satz erhalten (10 Ziffern und abis f, dh 4 Bits pro Zeichenfolge). Dies kann für einige Zwecke ausreichend sein, für kryptografische Zwecke jedoch zu wenig (fünf Zeichen von 16 Symbolen = 16 ^ 5 = 20 Bit = 1048576 Möglichkeiten).
Arc
3
array_rand($seed, 5)wird Array-Schlüssel zurückgeben, nicht Wert, so dass Ihr Code nicht funktioniert
Alumi
1
Ich denke, dass die Verwendung einer kryptografischen Hash-Funktion zum Generieren von zufälligen Zeichen zumindest unangemessen ist.
Gronostaj
Ist es auch möglich ", einen 'Backslash einzubeziehen $charset? Muss ich Escape-Sequenzen verwenden, um diese Zeichen einzuschließen?
Mai
1
Das zweite Snippet verwendet nicht einmal den $lenEingabeparameter ... haben Sie es vergessen?
TechNyquist
76
Wenn forSchleifen knapp sind, verwende ich Folgendes:
Interessante Lösung ... sehr prägnant, obwohl ich mich frage, ob dies schneller oder langsamer ist als für. Kann nicht die Mühe machen, Benchmarking :-)
Arc
@matthew str_shuffle wird kontinuierlich Duplikate produzieren
SCC
@ user2826057: str_shuffle('ab')würde geben aboder baaber nie aa. Das Hinzufügen der str_repeaterlaubt das. Aber das heißt, die Lösung, die ich gegeben habe, ist nicht wirklich ernst ... obwohl sie funktioniert.
Matthew
2
Es besteht eine Wahrscheinlichkeit von 1/60466176, dass dies geschieht, vorausgesetzt, das RNG ist gleichmäßig verteilt.
Matthew
1
Dies ist perfekt für unseren Anwendungsfall der Generierung von Gutscheincodes. Wir entfernten verwirrend Zeichen, wie l, i, 1, 0, O, etc. und aus 500 Gutscheinen bekommen keine Duplikate.
Luke Cousins
25
Ein schneller Weg besteht darin, die flüchtigsten Zeichen der Uniqid- Funktion zu verwenden.
Folgendes sollte die geringste Wahrscheinlichkeit einer Duplizierung bieten (möglicherweise möchten Sie es durch mt_rand()eine bessere Zufallszahlenquelle ersetzen, z. B. von /dev/*randomoder aus GUIDs):
Erstes Beispiel klüger mit $ result. = $ Zeichen [mt_rand (0, strlen ($ Zeichen) -1)]
hamboy75
In diesem Fall sollten Sie die Länge vorher bestimmen und mindestens in einer Variablen speichern. Die Verwendung strlen()in einer Schleife ist unnötig, insbesondere wenn Sie bereits wissen, dass sich der Zeichensatz in der Zwischenzeit nicht ändern wird.
Arc
Ich bezweifle es, PHP ist optimiert, es ist sowieso eine Option :)
Hamboy75
7
Ich benutze dafür immer die gleiche Funktion, normalerweise um Passwörter zu generieren. Es ist einfach zu bedienen und nützlich.
Ich glaube, dass die Verwendung von Hash-Funktionen ein Overkill für eine so einfache Aufgabe ist, wie das Erzeugen einer Folge von zufälligen hexadezimalen Ziffern. dechex+ mt_randerledigt den gleichen Job, jedoch ohne unnötige kryptografische Arbeit. str_padgarantiert eine Länge von 5 Zeichen der Ausgabezeichenfolge (wenn die Zufallszahl kleiner als 0x10000 ist).
Die doppelte Wahrscheinlichkeit hängt von mt_randder Zuverlässigkeit ab. Mersenne Twister ist bekannt für hochwertige Zufälligkeit, daher sollte es gut zur Aufgabe passen.
Ich wusste auch nicht, wie ich das machen sollte, bis ich daran dachte, PHPs arrayzu verwenden. Und ich bin mir ziemlich sicher, dass dies der einfachste Weg ist, eine zufällige Zeichenfolge oder Zahl mit Arrays zu generieren. Der Code:
Wie Archimedix hervorhob, garantiert dies nicht die Rückgabe einer "geringsten Möglichkeit der Duplizierung", da die Anzahl der Kombinationen für den angegebenen Zeichenbereich gering ist. Sie müssen entweder die Anzahl der Zeichen erhöhen oder zusätzliche (Sonder-) Zeichen in der Zeichenfolge zulassen. Die erste Lösung wäre in Ihrem Fall meiner Meinung nach vorzuziehen.
Die Verwendung time()ist bis zu 1 Million Mal vorhersehbarer als microtime().
Arc
Beachten Sie auch meine Kommentare zu Brads Antwort. Das größere Problem ist, dass der generierte Hash eine hexadezimale Darstellung ist, die aus 16 gültigen Zeichen besteht, sodass nur 1024 Variationen für übrig bleiben $str.
Arc
@Archimedix vielleicht, aber das OP hat nicht nach Sicherheit gefragt. Die Frage wurde so definiert, dass sie einen Algorithmus zur Zeichenfolgengenerierung enthält, der aus einer Kombination von 5 x 26 verschiedenen Zeichen besteht und Duplikate vermeidet. Dies ist wahrscheinlich für eine Bestätigungsreferenznummer in einem Registrierungsprozess (oder Abrechnungsprozess) oder so etwas
Yanick Rochon
Es war mein Verständnis , dass er tat fragen dest Möglichkeit, sich vervielfältigt , und dies hat 0,1% Wahrscheinlichkeit (1 in 1024) , die fast 1 waren in 1 Milliarde könnte.
Arc
Wenn Sie jedoch einen Referenzschlüssel mit 5 Zeichen generieren und diesem einen Kunden / Kunden geben müssen, möchten Sie ihn nicht " ˫§»⁋⅓" geben, nur weil er sicherer ist ... Sie erhöhen Ihren Referenzschlüssel auf 7 oder mehr Zeichen . (Übrigens: Korrektur in meinem vorherigen Kommentar, es ist 5x36 Zeichen)
Diese einfache PHP-Funktion hat bei mir funktioniert:
function cvf_ps_generate_random_code($length=10){
$string ='';// You can define your own characters here.
$characters ="23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";for($p =0; $p < $length; $p++){
$string .= $characters[mt_rand(0, strlen($characters)-1)];}return $string;}
Die neue password_hash()Funktion von PHP (*> = PHP 5.5) erledigt die Aufgabe, einen anständig langen Satz von Groß- und Kleinbuchstaben und -zahlen zu generieren.
Zwei concat. Zeichenfolgen vor und nach der password_hash$ random-Funktion können geändert werden.
Parameter für $random()* ($ a, $ b) sind tatsächlich substr()Parameter. :) :)
HINWEIS: Dies muss keine Funktion sein, es kann auch eine normale Variable sein. Als ein böser Singleliner, wie folgt:
Pro-Tipp - Geben Sie eine Erklärung an, wie Ihre Antwort das Problem des OP löst und warum sie sich möglicherweise von den anderen bereits bereitgestellten Antworten unterscheidet.
0-9a-zA-Z
?Random::alphanumericString($length)
können Sie Zeichenfolgen mit 0-9a-zA-Z abrufen, die aus kryptografisch sicheren Zufallsdaten stammen.Antworten:
Wäre meine beste Vermutung - es sei denn, Sie suchen auch nach Sonderzeichen:
Beispiel
Und zum einen basierend auf der Uhr (weniger Kollisionen, da sie inkrementell sind):
Hinweis: Inkrementell bedeutet leichter zu erraten. Wenn Sie dies als Salz- oder Verifizierungs-Token verwenden, tun Sie dies nicht. Ein Salz (jetzt) von "WCWyb" bedeutet in 5 Sekunden "WCWyg")
quelle
md5()
jedoch, dass Sie eine Zeichenfolge aus einem 16-Zeichen-Satz erhalten (10 Ziffern unda
bisf
, dh 4 Bits pro Zeichenfolge). Dies kann für einige Zwecke ausreichend sein, für kryptografische Zwecke jedoch zu wenig (fünf Zeichen von 16 Symbolen = 16 ^ 5 = 20 Bit = 1048576 Möglichkeiten).array_rand($seed, 5)
wird Array-Schlüssel zurückgeben, nicht Wert, so dass Ihr Code nicht funktioniert"
, einen'
Backslash einzubeziehen$charset
? Muss ich Escape-Sequenzen verwenden, um diese Zeichen einzuschließen?$len
Eingabeparameter ... haben Sie es vergessen?Wenn
for
Schleifen knapp sind, verwende ich Folgendes:quelle
str_shuffle('ab')
würde gebenab
oderba
aber nieaa
. Das Hinzufügen derstr_repeat
erlaubt das. Aber das heißt, die Lösung, die ich gegeben habe, ist nicht wirklich ernst ... obwohl sie funktioniert.l
,i
,1
,0
,O
, etc. und aus 500 Gutscheinen bekommen keine Duplikate.Ein schneller Weg besteht darin, die flüchtigsten Zeichen der Uniqid- Funktion zu verwenden.
Beispielsweise:
quelle
Sie können es einfach so versuchen:
Weitere Details: http://forum.arnlweb.com/viewtopic.php?f=7&t=25
quelle
Folgendes sollte die geringste Wahrscheinlichkeit einer Duplizierung bieten (möglicherweise möchten Sie es durch
mt_rand()
eine bessere Zufallszahlenquelle ersetzen, z. B. von/dev/*random
oder aus GUIDs):EDIT:
Wenn Sie über die Sicherheit betrifft, wirklich, sie nicht verwenden ,
rand()
odermt_rand()
, und stellen Sie sicher , dass Ihre Zufallsdaten Gerät ist eigentlich ein Gerät zu erzeugen zufällige Daten, keine reguläre Datei oder etwas vorhersehbar wie/dev/zero
.mt_rand()
als schädlich angesehen:https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
BEARBEITEN: Wenn Sie OpenSSL-Unterstützung in PHP haben, können Sie Folgendes verwenden
openssl_random_pseudo_bytes()
:quelle
strlen()
in einer Schleife ist unnötig, insbesondere wenn Sie bereits wissen, dass sich der Zeichensatz in der Zwischenzeit nicht ändern wird.Ich benutze dafür immer die gleiche Funktion, normalerweise um Passwörter zu generieren. Es ist einfach zu bedienen und nützlich.
quelle
Es scheint, als wäre str_shuffle eine gute Verwendung dafür. Setzen Sie den Shuffle mit den gewünschten Charakteren.
quelle
quelle
Wenn es in Ordnung ist, dass Sie nur Buchstaben AF erhalten, dann ist hier meine Lösung:
Ich glaube, dass die Verwendung von Hash-Funktionen ein Overkill für eine so einfache Aufgabe ist, wie das Erzeugen einer Folge von zufälligen hexadezimalen Ziffern.
dechex
+mt_rand
erledigt den gleichen Job, jedoch ohne unnötige kryptografische Arbeit.str_pad
garantiert eine Länge von 5 Zeichen der Ausgabezeichenfolge (wenn die Zufallszahl kleiner als 0x10000 ist).Die doppelte Wahrscheinlichkeit hängt von
mt_rand
der Zuverlässigkeit ab. Mersenne Twister ist bekannt für hochwertige Zufälligkeit, daher sollte es gut zur Aufgabe passen.quelle
Ich wusste auch nicht, wie ich das machen sollte, bis ich daran dachte, PHPs
array
zu verwenden. Und ich bin mir ziemlich sicher, dass dies der einfachste Weg ist, eine zufällige Zeichenfolge oder Zahl mit Arrays zu generieren. Der Code:Sie können diese Funktion so verwenden
quelle
Ähnlich wie Brad Christies Antwort, jedoch mit
sha1
Alrorithmus für Zeichen0-9a-zA-Z
und mit einem zufälligen Wert vorangestellt:Wenn Sie jedoch definierte (zulässige) Zeichen festgelegt haben:
** UPDATE **
Wie Archimedix hervorhob, garantiert dies nicht die Rückgabe einer "geringsten Möglichkeit der Duplizierung", da die Anzahl der Kombinationen für den angegebenen Zeichenbereich gering ist. Sie müssen entweder die Anzahl der Zeichen erhöhen oder zusätzliche (Sonder-) Zeichen in der Zeichenfolge zulassen. Die erste Lösung wäre in Ihrem Fall meiner Meinung nach vorzuziehen.
quelle
time()
ist bis zu 1 Million Mal vorhersehbarer alsmicrotime()
.$str
.˫§»⁋⅓
" geben, nur weil er sicherer ist ... Sie erhöhen Ihren Referenzschlüssel auf 7 oder mehr Zeichen . (Übrigens: Korrektur in meinem vorherigen Kommentar, es ist 5x36 Zeichen)funktioniert gut in PHP (PHP 5.4.4)
Live-Demo
quelle
Quelle: PHP-Funktion, die zufällige Zeichen generiert
Diese einfache PHP-Funktion hat bei mir funktioniert:
Verwendung:
quelle
Hier sind meine
random 5 cents
...Die neue
password_hash()
Funktion von PHP (*> = PHP 5.5) erledigt die Aufgabe, einen anständig langen Satz von Groß- und Kleinbuchstaben und -zahlen zu generieren.Zwei concat. Zeichenfolgen vor und nach der
password_hash
$ random-Funktion können geändert werden.Parameter für
$random()
* ($ a, $ b) sind tatsächlichsubstr()
Parameter. :) :)HINWEIS: Dies muss keine Funktion sein, es kann auch eine normale Variable sein. Als ein böser Singleliner, wie folgt:
quelle
quelle
Ich benutze immer das:
Wenn Sie es aufrufen, legen Sie die Länge der Zeichenfolge fest.
Sie können auch die möglichen Zeichen in der Zeichenfolge ändern
$a
.quelle