Diese Frage ist nicht wirklich ein Problem bei der Suche nach einer Lösung, sondern eher eine Frage der einfachen Neugier. Die PHP-Uniqid-Funktion verfügt über ein Entropie-Flag, um die Ausgabe "eindeutiger" zu machen. Ich habe mich gefragt, wie wahrscheinlich es ist, dass diese Funktion mehr als einmal dasselbe Ergebnis liefert, wenn more_entropy wahr ist, im Gegensatz dazu, wenn dies nicht der Fall ist. Mit anderen Worten, wie eindeutig ist Uniqid, wenn more_entropy aktiviert ist, im Vergleich zu deaktiviert? Gibt es Nachteile, wenn more_entropy ständig aktiviert ist?
76
uniqid
mitmore_entropy
set nur etwa 92 Bit Entropie (23 Hexbit). Um zu verstehen, warum das nicht gut für die Einzigartigkeit ist, siehe Das Geburtstagsproblem ...more_entropy
beträgt ungefähr 30 Bit Entropie (neun Dezimalstellen), der Mikrosekunden-Teil ist ungefähr 20 (sechs Dezimalstellen), woher kommt der Rest? Sie müssten die Sekunde aus einem Bereich von 100.000 Jahren auswählen, um 42 Entropiebits zu erhalten.Antworten:
Update, März 2014:
Erstens ist es wichtig zu beachten, dass dies
uniqid
eine Fehlbezeichnung ist, da keine eindeutige ID garantiert wird.Gemäß der PHP-Dokumentation :
Und
Wenn Sie mehr Entropie auf true setzen, wird ein eindeutigerer Wert generiert. Die Ausführungszeit ist jedoch länger (wenn auch zu einem winzigen Grad).
Beachten Sie die Linie
increases the likelihood that the result will be unique
und nicht, dass dies die Eindeutigkeit garantiert .Sie können "endlos" bis zu einem gewissen Punkt nach Einzigartigkeit streben und diese mithilfe einer beliebigen Anzahl von Verschlüsselungsroutinen verbessern, indem Sie Salze und dergleichen hinzufügen - dies hängt vom Zweck ab.
Ich würde empfehlen, die Kommentare zum Hauptthema von PHP zu lesen, insbesondere:
http://www.php.net/manual/en/function.uniqid.php#96898
http://www.php.net/manual/en/function.uniqid.php#96549
http://www.php.net/manual/en/function.uniqid.php#95001
Was ich empfehlen würde, ist herauszufinden, warum Sie Eindeutigkeit benötigen, aus Sicherheitsgründen (dh um eine Verschlüsselungs- / Verschlüsselungsroutine zu ergänzen)? Auch Wie einzigartig braucht es zu sein? Schauen Sie sich zum Schluss die Geschwindigkeitsüberlegung an. Die Eignung ändert sich mit den zugrunde liegenden Überlegungen.
quelle
uniqid
(oder es sind Derivate) nichts für Sicherheitsfragen. PHP bietet eine ganze Reihe von kryptosicheren Zufallsgeneratoren, wie zum Beispiel :openssl_random_pseudo_bytes
. Bitte verwenden Sie das richtige Werkzeug für den Job.do{} while(collision)
. Ich verwende diesen Ansatz zum Beispiel beim Generieren von Pfaden für hochgeladene Dateien.Dinge sind nur dann einzigartig, wenn Sie überprüfen, ob sie noch nicht vorhanden sind. Es spielt keine Rolle, mit welcher Funktion Sie eine 'zufällige' Zeichenfolge oder ID generieren - wenn Sie nicht überprüfen, ob es sich nicht um ein Duplikat handelt, besteht immer diese Chance ..;)
Während uniqid auf der aktuellen Zeit basiert, gilt der obige Warnhinweis weiterhin - es hängt nur davon ab, wo Sie diese "eindeutigen IDs" verwenden. Der Hinweis auf all dies ist, wo es "einzigartiger" sagt. Einzigartig ist einzigartig ist einzigartig. Wie man etwas mehr oder weniger Einzigartiges haben kann, ist für mich etwas verwirrend!
Wenn Sie wie oben prüfen und all diese Dinge kombinieren, erhalten Sie etwas, das sich der Einzigartigkeit nähert, aber alles hängt davon ab, wo die Schlüssel verwendet werden und im Kontext. Hoffentlich hilft das!
quelle
10^47
Jahre jeweils 1 Billion Zahlen pro Sekunde zu generieren, nur um eine 50% ige Chance auf eine Kollision zu haben ... Also ja, mit einer ausreichend hohen Obergrenze Auf der Zufallszahl UND einem ausreichend guten RNG können Sie die Einzigartigkeit nur mit Zufälligkeit simulieren ...rand()
hätten, wenn sie den beschissenen Bestand ihres Compilers verwenden , bei der ersten Iteration eine Kollisionswahrscheinlichkeit von > 90% . Wenn Sie Einzigartigkeit benötigen , ist sogar eine Kollisionswahrscheinlichkeit von 0,001% zu groß.Aus den Diskussionen über die Funktion auf der PHP-Handbuchseite:
Mit anderen Worten, ohne "more_entropy" ist die Funktion absolut schrecklich und sollte niemals verwendet werden, Punkt. Gemäß der Dokumentation verwendet das Flag einen "kombinierten linearen Kongruenzgenerator", um "Entropie hinzuzufügen". Nun, das ist ein ziemlich schwaches RNG. Also würde ich diese Funktion komplett überspringen und etwas verwenden, das auf mt_rand basiert, mit einem guten Startwert für Dinge, die nicht sicherheitsrelevant sind, und SHA-256 für Dinge, die nicht sicherheitsrelevant sind.
quelle
Ohne das Flag more_unique wird der Unix-Zeitstempel mit einem Mikrosekundenzähler zurückgegeben. Wenn also zwei Aufrufe mit derselben Mikrosekunde getätigt werden, geben sie dieselbe 'eindeutige' ID zurück.
Von dort ist es eine Frage, wie wahrscheinlich das ist. Die Antwort ist nicht sehr, aber nicht in abschätzbarem Maße. Wenn Sie eine eindeutige ID benötigen und diese häufig generieren (oder mit Daten arbeiten, die an anderer Stelle generiert wurden), rechnen Sie nicht damit, dass diese absolut eindeutig ist.
quelle
Das relevante Bit aus dem Quellcode ist
if (more_entropy) { uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10); } else { uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec); }
So
more_entropy
fügt neun etwas zufällig Dezimalstellen (php_combined_lcg()
liefert einen Wert in(0,1)
) - , die 29,9 Bits der Entropie ist, Tops (in Wirklichkeit wahrscheinlich weniger als LCG ist kein kryptographisch sicheren Pseudozufallszahlengenerator).quelle