Sven Rautenberg: Lösung ist:

Beitrag lesen

Moin!

uniqid() ist aber nicht eindeutig! Ich habe Code in meiner Software, die aufgrund von Nicht-Eindeutigkeit von uniqid ()

Beschreibung von php.net: uniqueid() ... "Gibt eine eindeutige ID mit Präfix zurück, die auf der aktuellen Zeit in Mikrosekunden basiert."

Könntest Du bitte auf die, sehr wahrscheinlich vom Problem des TO doch recht ordentlich abweichenden Umstände eingehen, unter denen es Dir gelungen ist, mit unique_id() nicht unique ids zu erzeugen?

Unittests haben unregelmäßig Fehler angezeigt, deren Analyse ergeben hat, dass dieselbe uniqid() verwendet wurde, die schon einmal erzeugt worden war. Das Abfangen dieser speziellen Situation hat das Problem behoben.

Ach ja: Möglicherweise waren zwei Server parallel am Werk - warum die aber auf die Mikrosekunde identisch uniqid() aufgerufen bekommen haben sollen bei Requests, die mehrere Sekunden auseinanderliegen, ist nicht nachvollziehbar - es ist aber aufgrund der Entstehungsmethode von uniqid() jedenfalls nicht garantiert, dass es nicht zu Wiederholungen kommt. Wenn beispielsweise der ntpd im Hintergrund an der Uhr dreht, kommt eventuell dieselbe Uhrzeit zweimal. Servercluster, Mehrkernsysteme und virtualisierte Umgebungen (Cloud etc.) sind ja außerdem nichts ungewöhnliches.

13 Stellen hex sind 6,5 Bbyte sind 54 bit, sind also 2^54 Millisekunden. Wiederholung ergo frühestens nach

  • 18014398509481984 Millisekunden
  • 18014398509481 Sekunden
  • 300239975158 Minuten
  • 5003999585 Stunden
  • 208499982 Tagen
  • 570800 Jahren
  • 142710 Rechnergenerationen (a 4 Jahre)
  • 22833 mesnchl. Generationen (a 25 Jahre)

Du müsstest ergo mit passender Software auf einem Mehrprozessorsystem die ids erzeugt haben oder auf sehr vielen Rechnern uniqueid() gestartet haben, wodurch es zu dem Umstand kam, dass die Uhrzeit jeweils bis auf die Millisekunde stimmte. Nicht ganz undenkbar.

Es reicht, dass das undenkbare real passiert ist, und zwar so regelmäßig, dass nicht nur irgendein Testlauf unerwartet gescheitert ist, sondern nachprüfbar so häufig, dass es genervt hat.

Der Code für die uniqid() ist übrigens der hier: https://github.com/php/php-src/blob/master/ext/standard/uniqid.c#L72-L83

Acht Hexzahlen aus den Sekunden plus fünf Hexzahlen aus den Mikrosekunden, die zuvor modulo 0x100000 genommen wurden (was nichts ändert - Mikrosekunden werden nie größer als eine Million).

Grüße Sven