Diese Frage ist nicht wirklich ein Problem, das nach einer Lösung sucht, sondern nur eine Frage der einfachen Neugier. Die PHP-Funktion uniqid hat ein Flag für mehr Entropie, um die Ausgabe “einzigartiger” zu machen. Ich habe mich gefragt, wie wahrscheinlich es ist, dass diese Funktion dasselbe Ergebnis mehr als einmal liefert, wenn more_entropy wahr ist, im Vergleich dazu, wenn dies nicht der Fall ist. Mit anderen Worten, wie eindeutig ist uniqid, wenn more_entropy aktiviert ist, im Vergleich zu deaktiviertem? Gibt es irgendwelche Nachteile, wenn more_entropy die ganze Zeit aktiviert ist?
Wie einzigartig ist uniqid?
GordonM
SW4
Aktualisierung, März 2014:
Zunächst ist es wichtig, dies zu beachten uniqid
ist ein bisschen irreführend, da es keine eindeutige ID garantiert.
Pro die PHP-Dokumentation:
WARNUNG!
Diese Funktion erstellt keine zufällige oder unvorhersehbare Zeichenfolge. Diese Funktion darf nicht aus Sicherheitsgründen verwendet werden. Verwenden Sie kryptografisch sichere Zufallsfunktionen/-generatoren und kryptografisch sichere Hash-Funktionen, um unvorhersehbare sichere IDs zu erstellen.
Und
Diese Funktion generiert keine kryptografisch sicheren Token, tatsächlich unterscheidet sich der Rückgabewert kaum, ohne dass zusätzliche Parameter übergeben werden Mikrozeit (). Wenn Sie kryptografisch sichere Token generieren müssen, verwenden Sie openssl_random_pseudo_bytes().
Wenn Sie more-entropy auf true setzen, wird ein eindeutigerer Wert generiert, die Ausführungszeit ist jedoch länger (wenn auch geringfügig), so die Dokumentation:
Wenn auf TRUE gesetzt, fügt uniqid() am Ende des Rückgabewerts zusätzliche Entropie hinzu (unter Verwendung des kombinierten linearen Kongruenzgenerators), was die Wahrscheinlichkeit erhöht, dass das Ergebnis eindeutig ist.
Beachte die Linie increases the likelihood that the result will be unique
und nicht das ist Wille Garantie Einzigartigkeit.
Sie können bis zu einem gewissen Punkt “endlos” nach Einzigartigkeit streben und diese mit einer beliebigen Anzahl von Verschlüsselungsroutinen verbessern, indem Sie hinzufügen Salze und dergleichen – es hängt vom Zweck ab.
Ich würde empfehlen, sich die Kommentare zum Hauptthema PHP anzusehen, 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 zu trainieren warum Sie brauchen Eindeutigkeit, ist es für die Sicherheit (dh um eine Verschlüsselungs-/Verschlüsselungsroutine hinzuzufügen)? Ebenfalls, Wie einzigartig muss es sein? Betrachten Sie schließlich die Geschwindigkeitsbetrachtung. Die Eignung ändert sich mit den zugrunde liegenden Überlegungen.
-
Die wichtigste Lehre aus diesen Funktionskommentaren ist, dass uuid an sich eine sehr gefährliche Kennung ist, die als Cookie-/clientlesbare ID übergeben werden kann, aber als lokale/geschützte eindeutige ID einige gute Verwendungszwecke hat, nämlich Geschwindigkeit. 2,5 Cent.
– Dr. Perdix
1. November 10 um 15:26 Uhr
-
Ich weiß nicht, ob das schon offensichtlich war, aber benutze es nicht
uniqid
(oder seine Derivate) für alles, was mit Sicherheit zu tun hat. PHP bietet eine ganze Reihe kryptosicherer Zufallsgeneratoren, wie zum Beispiel:openssl_random_pseudo_bytes
. Bitte verwenden Sie das richtige Werkzeug für den Job.– Halkyon
4. Dezember 13 um 16:01 Uhr
-
Unter der Annahme, dass keine 2 Dateien zur selben Mikrosekunde gespeichert werden, wäre ein Unix-Mikrosekunden-Zeitstempel für jede Datei eindeutig.
– CMCDragonkai
12. Januar 14 um 17:01 Uhr
-
Es ist statistisch unwahrscheinlich, dass Sie eine Kollision bekommen, aber nicht unmöglich. Setzen Sie Ihre Uniqid-Generation in a
do{} while(collision)
. Ich verwende diesen Ansatz zum Beispiel beim Generieren von Pfaden für hochgeladene Dateien.– afilina
12. August 15 um 14:04 Uhr
-
Ich bin mir nicht sicher, warum diese Antwort akzeptiert wurde. Einzigartig != zufällig/unvorhersehbar
– gadelat
19. Mai ’16 um 8:40 Uhr
Dinge sind nur dann einzigartig, wenn Sie überprüfen, ob sie nicht bereits existieren. Es spielt keine Rolle, welche Funktion Sie verwenden, um eine “zufällige” Zeichenfolge oder ID zu generieren – wenn Sie nicht doppelt ü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 werden. Der Schlüssel zu all dem ist, wo es heißt “mehr einzigartig”. Einzigartig ist einzigartig ist einzigartig. Wie man etwas haben kann, das mehr oder weniger einzigartig ist, ist für mich ein bisschen verwirrend!
Wenn Sie wie oben prüfen und all diese Dinge kombinieren, erhalten Sie am Ende etwas, das sich der Einzigartigkeit nähert, aber es hängt alles davon ab, wo die Schlüssel verwendet werden, und vom Kontext. Hoffentlich hilft das!
-
Da ist ein riesig Unterschied zwischen “Die Wahrscheinlichkeit einer Kollision ist eins zu zehntausend” und “Die Wahrscheinlichkeit einer Kollision ist geringer, als wenn jeder einzelne Benutzer des Programms gleichzeitig vom Blitz getroffen wird”. Ein 128-Bit-Wert, der von einem guten RNG mit einem guten Seed generiert wird, ist so nahe daran, “wirklich” einzigartig zu sein, dass es keine Rolle spielt, wenn man die unglaublich hohen Kosten bedenkt, etwas zu bekommen nachweislich (und unvorhersehbar) einzigartig.
– Michael Borgwardt
1. November 10 um 15:20 Uhr
-
Nur um Ihren Standpunkt zu verdeutlichen, @Michael: Für 128 Bit müssten alle in den USA (300 Millionen) etwa einen Tag lang 1 Million Zahlen pro Sekunde generieren, um eine Kollisionswahrscheinlichkeit von 50 % zu erreichen … Für 512 Bits benötigen Sie jeden Körper auf der Erde (7 Milliarden Menschen), um jeweils 1 Billion Zahlen pro Sekunde für den nächsten zu generieren
10^47
Jahre, nur um eine Kollisionswahrscheinlichkeit von 50% zu haben … Also ja, mit einer ausreichend hohen Obergrenze für die Zufallszahl UND einem ausreichend guten RNG können Sie Eindeutigkeit nur mit Zufälligkeit simulieren …– ircmaxell
1. November 10 um 15:35 Uhr
-
Ich stimme Ihren Idealweltbeispielen wie oben vollkommen zu. Die Chancen sind minimal. Die Zufälligkeit ist jedoch in den Implementierungen, auf die in der ursprünglichen Frage Bezug genommen wird, nicht perfekt, und ich behaupte, dass die Domäne, in der diese eindeutige Nummer verwendet wird, wichtig ist. Wenn Sie 1000 Server hätten, die jeweils “eindeutige” IDs basierend auf Microtimes erstellen, und davon ausgehen, dass sie “nur weil” einzigartig sind, dann können Sie sich irgendwann verbrennen. Ignorieren Sie alle Macken im Code.. Fehler oder was auch immer. Der Unterschied besteht hier zwischen Realität und Theorie, und deshalb prüfen wir 😉
– dmp
1. November 10 um 15:58 Uhr
-
„Das Prinzip, kleine Mengen an endlicher Unwahrscheinlichkeit zu erzeugen, indem man einfach die logischen Schaltkreise eines Bambleweeny 57 Sub-Meson-Gehirns an einen Atomvektorplotter anhängt, der in einem starken Brownschen Bewegungserzeuger (sagen wir einer schönen heißen Tasse Tee) hängt, wurde natürlich gut verstanden .”
– dmp
1. November 10 um 15:58 Uhr
-
@ircmaxell: Der Haken ist, dass diese Zahlen erforderlich sind Real Zufälligkeit und damit ein echtes RNG. Sie könnten es nicht einmal mit einem PRNG mit > 128 Bit internem Status simulieren, es sei denn, Sie hätten auch eine Möglichkeit, es mit einem eindeutigen/zufälligen > 128-Bit-Wert zu versehen. Aber das ist genau das Problem, das Sie lösen müssen! Und alles andere garantiert Kollisionen praktisch. Dieselben 300 Millionen Leute, die den beschissenen Bestand ihres Compilers benutzten
rand()
hätte eine Kollisionswahrscheinlichkeit von > 90 % bei der allerersten Iteration. Außerdem, wenn Sie müssen Eindeutigkeit, selbst eine Kollisionswahrscheinlichkeit von 0,001 % ist zu viel.– chao
22. August 13 um 13:13 Uhr
Aus den Diskussionen über die Funktion auf der PHP-Handbuchseite:
Wie andere unten anmerken, gibt diese Funktion ohne Präfix und ohne “hinzugefügte Entropie” einfach den UNIX-Zeitstempel mit hinzugefügtem Mikrosekundenzähler als Hexadezimalzahl zurück; es ist mehr oder weniger nur microtime() in Hexit-Form.
[…]
Beachtenswert ist auch, dass, da microtime() nur auf Systemen funktioniert, auf denen gettimeofday() > vorhanden ist, was Windows nativ NICHT tut, uniqid() in einer Windows-Umgebung möglicherweise nur den UNIX-Zeitstempel mit einer Auflösung von einer Sekunde liefert.
Mit anderen Worten, ohne “more_entropy” ist die Funktion absolut schrecklich und sollte niemals verwendet werden, Punkt. Laut Dokumentation verwendet das Flag einen “kombinierten linearen kongruenten Generator”, um “Entropie hinzuzufügen”. Nun, das ist ein ziemlich schwacher RNG. Also würde ich diese Funktion komplett überspringen und etwas verwenden, das auf basiert mt_rand mit einem guten Seed für Dinge, die nicht sicherheitsrelevant sind, und SHA-256 für Dinge, die es sind.
Ohne das more_unique-Flag wird der Unix-Zeitstempel mit einem Mikrosekundenzähler zurückgegeben. Wenn also zwei Aufrufe zur selben Mikrosekunde getätigt werden, geben sie dieselbe „eindeutige“ ID zurück.
Von daher ist die Frage, wie wahrscheinlich das ist. Die Antwort ist, nicht sehr, aber nicht in einem diskontierbaren Maße. wenn du müssen eine eindeutige ID haben und diese häufig generieren (oder mit anderswo generierten Daten arbeiten), verlassen Sie sich nicht darauf, dass sie absolut einzigartig ist.
Das relevante Bit aus der 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ällige Dezimalziffern hinzu (php_combined_lcg()
gibt einen Wert in zurück (0,1)
) – das sind 29,9 Bit Entropie, Spitzenwerte (in Wirklichkeit wahrscheinlich weniger, da LCG kein kryptografisch sicherer Pseudozufallszahlengenerator ist).
.
Wenn Sie etwas wollen, das ist stets einzigartig, müssten Sie a implementieren GUID. So ziemlich alles andere wird schließlich kollidieren, da die Funktion nur so viel Entropie enthält. Beispielsweise,
uniqid
mitmore_entropy
Satz gibt nur etwa 92 Bits Entropie (23 Hexbits). Um zu verstehen, warum das nicht gut für die Einzigartigkeit ist, siehe Das Geburtstagsproblem…– ircmaxell
1. November 10 um 15:16 Uhr
@ircmaxell danke für den Hinweis auf das Geburtstagsproblem, es ist ziemlich interessant. Es sollte unbedingt in der Antwort erwähnt werden.
– Peter Peller
26. Oktober 11 um 15:11 Uhr
uniqid() ist keine Hash-Funktion, daher gilt das Geburtstagsproblem nicht dafür. Es hat jedoch seine Schwachstellen.
– Joel Mellon
6. November 12 um 1:16 Uhr
@ircmaxell woher kommt diese Nummer?
more_entropy
ist ungefähr 30 Bit Entropie (neun Dezimalstellen), der Mikrosekundenteil ist ungefähr 20 (sechs Dezimalstellen), woher kommt der Rest? Sie müssten die zweite aus einem Bereich von 100.000 Jahren auswählen, um 42 Bit Entropie zu erhalten.– Tgr
24. Juli 16 um 0:12 Uhr