From d9726aff0ec1e23267f4d7ab543e727c8ba041bd Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Wed, 3 Dec 2025 00:48:13 +0100 Subject: [PATCH] feat: add UUID v7 generator helper method (#17) This PR adds a `UUID::v7()` method for generating version 7 UUIDs, which have several performace advantages over v4 when stored in database indecies. Reviewed-on: https://codeberg.org/vlw/scaffold/pulls/17 --- src/Helpers/UUID.php | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/Helpers/UUID.php b/src/Helpers/UUID.php index c7d0914..5861455 100644 --- a/src/Helpers/UUID.php +++ b/src/Helpers/UUID.php @@ -26,6 +26,54 @@ return "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"; } + /** + * Generate a version 7 UUID + * + * @return string + */ + function v7(): string { + static $last_unix_epoch = null; + static $sequence = 0; + + // Get current time in milliseconds + $unix_ms = (int) microtime(true) * 1000; + + // Compensate for same-ms collisions + if ($unix_ms === $last_unix_epoch) { + $sequence++; + // Keep within the 14-bit sequence range + $sequence &= 0x3FFF; + + // Bump time slightly to avoid collision + if ($sequence === 0) { + $unix_ms++; + } + } else { + // Random start per ms + $sequence = random_int(0, 0x3FFF); + $last_unix_epoch = $unix_ms; + } + + $time_high = ($unix_ms >> 16) & 0xFFFFFFFF; + $time_low = $unix_ms & 0xFFFF; + + $time_hi_and_version = ($time_low & 0x0FFF) | (0x7 << 12); + $clock_seq_hi_and_reserved = ($sequence & 0x3FFF) | 0x8000; + + // Generate 6 bytes (48 bits) of randomness + $rand_bytes = random_bytes(6); + $rand_hex = bin2hex($rand_bytes); + + return sprintf( + "%08x-%04x-%04x-%04x-%012s", + $time_high, + $time_low, + $time_hi_and_version, + $clock_seq_hi_and_reserved, + $rand_hex + ); + } + /** * Generate a version 4 UUID *