@@ -64,6 +64,17 @@ public static function generate(\DateTimeInterface $time = null): string
64
64
self ::$ rand [1 ] &= 0x03FF ;
65
65
self ::$ time = $ time ;
66
66
} else {
67
+ // Within the same ms, we increment the rand part by a random 24-bit number.
68
+ // Instead of getting this number from random_bytes(), which is slow, we get
69
+ // it by sha512-hashing self::$seed. This produces 64 bytes of entropy,
70
+ // which we need to split in a list of 24-bit numbers. unpack() first splits
71
+ // them into 16 x 32-bit numbers; we take the first byte of each of these
72
+ // numbers to get 5 extra 24-bit numbers. Then, we consume those numbers
73
+ // one-by-one and run this logic every 21 iterations.
74
+ // self::$rand holds the random part of the UUID, split into 5 x 16-bit
75
+ // numbers for x86 portability. We increment this random part by the next
76
+ // 24-bit number in the self::$seedParts list and decrement self::$seedIndex.
77
+
67
78
if (!self ::$ seedIndex ) {
68
79
$ s = unpack ('l* ' , self ::$ seed = hash ('sha512 ' , self ::$ seed , true ));
69
80
$ s [] = ($ s [1 ] >> 8 & 0xFF0000 ) | ($ s [2 ] >> 16 & 0xFF00 ) | ($ s [3 ] >> 24 & 0xFF );
@@ -75,7 +86,7 @@ public static function generate(\DateTimeInterface $time = null): string
75
86
se
660D
lf ::$ seedIndex = 21 ;
76
87
}
77
88
78
- self ::$ rand [5 ] = 0xFFFF & $ carry = self ::$ rand [5 ] + (self ::$ seedParts [self ::$ seedIndex --] & 0xFFFFFF );
89
+ self ::$ rand [5 ] = 0xFFFF & $ carry = self ::$ rand [5 ] + 1 + (self ::$ seedParts [self ::$ seedIndex --] & 0xFFFFFF );
79
90
self ::$ rand [4 ] = 0xFFFF & $ carry = self ::$ rand [4 ] + ($ carry >> 16 );
80
91
self ::$ rand [3 ] = 0xFFFF & $ carry = self ::$ rand [3 ] + ($ carry >> 16 );
81
92
self ::$ rand [2 ] = 0xFFFF & $ carry = self ::$ rand [2 ] + ($ carry >> 16 );
0 commit comments