Skip to content

Commit

Permalink
bug #52367 [Uid] Fix UuidV7 collisions within the same ms (nicolas-gr…
Browse files Browse the repository at this point in the history
…ekas)

This PR was merged into the 6.3 branch.

Discussion
----------

[Uid] Fix UuidV7 collisions within the same ms

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #52338
| License       | MIT

Off-by-one errors...

Commits
-------

e3bf65b [Uid] Fix UuidV7 collisions within the same ms
  • Loading branch information
nicolas-grekas committed Oct 31, 2023
2 parents 6c62a62 + e3bf65b commit fb913d9
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/Symfony/Component/Uid/UuidV7.php
Expand Up @@ -64,6 +64,17 @@ public static function generate(\DateTimeInterface $time = null): string
self::$rand[1] &= 0x03FF;
self::$time = $time;
} else {
// Within the same ms, we increment the rand part by a random 24-bit number.
// Instead of getting this number from random_bytes(), which is slow, we get
// it by sha512-hashing self::$seed. This produces 64 bytes of entropy,
// which we need to split in a list of 24-bit numbers. unpack() first splits
// them into 16 x 32-bit numbers; we take the first byte of each of these
// numbers to get 5 extra 24-bit numbers. Then, we consume those numbers
// one-by-one and run this logic every 21 iterations.
// self::$rand holds the random part of the UUID, split into 5 x 16-bit
// numbers for x86 portability. We increment this random part by the next
// 24-bit number in the self::$seedParts list and decrement self::$seedIndex.

if (!self::$seedIndex) {
$s = unpack('l*', self::$seed = hash('sha512', self::$seed, true));
$s[] = ($s[1] >> 8 & 0xFF0000) | ($s[2] >> 16 & 0xFF00) | ($s[3] >> 24 & 0xFF);
Expand All @@ -75,7 +86,7 @@ public static function generate(\DateTimeInterface $time = null): string
self::$seedIndex = 21;
}

self::$rand[5] = 0xFFFF & $carry = self::$rand[5] + (self::$seedParts[self::$seedIndex--] & 0xFFFFFF);
self::$rand[5] = 0xFFFF & $carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xFFFFFF);
self::$rand[4] = 0xFFFF & $carry = self::$rand[4] + ($carry >> 16);
self::$rand[3] = 0xFFFF & $carry = self::$rand[3] + ($carry >> 16);
self::$rand[2] = 0xFFFF & $carry = self::$rand[2] + ($carry >> 16);
Expand Down

0 comments on commit fb913d9

Please sign in to comment.