@@ -137,33 +137,23 @@ public function getDateTime(): \DateTimeImmutable
137
137
}
138
138
139
139
if (4 > \strlen ($ time )) {
140
- $ time = str_pad ( $ time , 4 , ' 0 ' , \ STR_PAD_LEFT ) ;
140
+ $ time = ' 000 ' . $ time ;
141
141
}
142
142
143
143
return \DateTimeImmutable::createFromFormat ('U.u ' , substr_replace ($ time , '. ' , -3 , 0 ));
144
144
}
145
145
146
146
public static function generate (\DateTimeInterface $ time = null ): string
147
147
{
148
- if (null === $ time ) {
149
- return self ::doGenerate ();
150
- }
151
-
152
- if (0 > $ time = substr ($ time ->format ('Uu ' ), 0 , -3 )) {
153
- throw new \InvalidArgumentException ('The timestamp must be positive. ' );
154
- }
155
-
156
- return self ::doGenerate ($ time );
157
- }
158
-
159
- private static function doGenerate (string $ mtime = null ): string
160
- {
161
- if (null === $ time = $ mtime ) {
148
+ if (null === $ mtime = $ time ) {
162
149
$ time = microtime (false );
163
150
$ time = substr ($ time , 11 ).substr ($ time , 2 , 3 );
151
+ } elseif (0 > $ time = $ time ->format ('Uv ' )) {
152
+ throw new \InvalidArgumentException ('The timestamp must be positive. ' );
164
153
}
165
154
166
- if ($ time !== self ::$ time ) {
155
+ if ($ time > self ::$ time || (null !== $ mtime && $ time !== self ::$ time )) {
156
+ randomize:
167
157
$ r = unpack ('nr1/nr2/nr3/nr4/nr ' , random_bytes (10 ));
168
158
$ r ['r1 ' ] |= ($ r ['r ' ] <<= 4 ) & 0xF0000 ;
169
159
$ r ['r2 ' ] |= ($ r ['r ' ] <<= 4 ) & 0xF0000 ;
@@ -173,19 +163,22 @@ private static function doGenerate(string $mtime = null): string
173
163
self ::$ rand = array_values ($ r );
174
164
self ::$ time = $ time ;
175
165
} elseif ([0xFFFFF , 0xFFFFF , 0xFFFFF , 0xFFFFF ] === self ::$ rand ) {
176
- if (null === $ mtime ) {
177
- usleep (100 );
166
+ if (\PHP_INT_SIZE >= 8 || 10 > \strlen ($ time = self ::$ time )) {
167
+ $ time = (string ) (1 + $ time );
168
+ } elseif ('999999999 ' === $ mtime = substr ($ time , -9 )) {
169
+ $ time = (1 + substr ($ time , 0 , -9 )).'000000000 ' ;
178
170
} else {
179
- self :: $ rand = [ 0 , 0 , 0 , 0 ] ;
171
+ $ time = substr_replace ( $ time , str_pad (++ $ mtime , 9 , ' 0 ' , \ STR_PAD_LEFT ), - 9 ) ;
180
172
}
181
173
182
- return self :: doGenerate ( $ mtime ) ;
174
+ goto randomize ;
183
175
} else {
184
176
for ($ i = 3 ; $ i >= 0 && 0xFFFFF === self ::$ rand [$ i ]; --$ i ) {
185
177
self ::$ rand [$ i ] = 0 ;
186
178
}
187
179
188
180
++self ::$ rand [$ i ];
181
+ $ time = self ::$ time ;
189
182
}
190
183
191
184
if (\PHP_INT_SIZE >= 8 ) {
0 commit comments