Skip to content

Commit 651ce89

Browse files
authored
Proper v7 subsec encoding (#32)
1 parent 4c7e0ec commit 651ce89

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var_dump($uuid6_first < $uuid6_second); // bool(true)
6060

6161
// Generate a version 7 (lexicographically sortable) UUID
6262
$uuid7_first = UUID::uuid7();
63-
echo $uuid7_first . "\n"; // e.g. 061a3d43-61d0-7cf4-bfce-753dadab55e1
63+
echo $uuid7_first . "\n"; // e.g. 061d0edc-bea0-75cc-9892-f6295fd7d295
6464
$uuid7_second = UUID::uuid7();
6565
var_dump($uuid7_first < $uuid7_second); // bool(true)
6666

@@ -114,8 +114,8 @@ var_dump($cmp3 === 0); // bool(true)
114114
// Extract Unix time from versions 6 and 7 as a string.
115115
$uuid6_time = UUID::getTime('1ebacf4f-a4a8-68ee-b4ec-618c14d005d5');
116116
var_dump($uuid6_time); // string(18) "1620145373.6118510"
117-
$uuid7_time = UUID::getTime('061a3d43-61d0-7cf4-bfce-753dadab55e1');
118-
var_dump($uuid7_time); // string(18) "1638126646.1903860"
117+
$uuid7_time = UUID::getTime('061d0edc-bea0-75cc-9892-f6295fd7d295');
118+
var_dump($uuid7_time); // string(18) "1641082315.9141510"
119119

120120
// Extract the UUID version.
121121
$uuid_version = UUID::getVersion('2140a926-4a47-465c-b622-4571ad9bb378');

src/UUID.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ private static function uuidFromHex(string $uhex, int $version): string
134134
);
135135
}
136136

137+
/** @internal */
138+
private static function encodeSubsec(int $value): int
139+
{
140+
return intdiv($value * 2 ** 24, 10 ** 7);
141+
}
142+
143+
/** @internal */
144+
private static function decodeSubsec(int $value): int
145+
{
146+
return (int) ceil($value * 10 ** 7 / 2 ** 24);
147+
}
148+
137149
/**
138150
* Generate a version 3 UUID based on the MD5 hash of a namespace identifier
139151
* (which is a UUID) and a name (which is a string).
@@ -201,6 +213,7 @@ public static function uuid6(): string
201213
public static function uuid7(): string
202214
{
203215
[$unixts, $subsec] = self::getUnixTime();
216+
$subsec = self::encodeSubsec($subsec);
204217
$uhex = substr(str_pad(dechex($unixts), 9, '0', \STR_PAD_LEFT), -9);
205218
$uhex .= substr_replace(str_pad(dechex($subsec), 6, '0', \STR_PAD_LEFT), '7', -3, 0);
206219
$uhex .= bin2hex(random_bytes(8));
@@ -246,7 +259,7 @@ public static function getTime(string $uuid): ?string
246259
$retval = substr_replace(strval(hexdec($timehex) - self::TIME_OFFSET_INT), '.', -7, 0);
247260
} elseif ($version === 7) {
248261
$unixts = hexdec(substr($timehex, 0, 10));
249-
$subsec = str_pad(strval(hexdec(substr($timehex, 10))), 7, '0', \STR_PAD_LEFT);
262+
$subsec = str_pad(strval(self::decodeSubsec(hexdec(substr($timehex, 10)))), 7, '0', \STR_PAD_LEFT);
250263
$retval = $unixts . '.' . $subsec;
251264
}
252265
return $retval;

tests/UuidTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ public function testKnownGetTime()
191191
{
192192
$uuid6_time = UUID::getTime('1ebacf4f-a4a8-68ee-b4ec-618c14d005d5');
193193
$this->assertSame($uuid6_time, '1620145373.6118510');
194-
$uuid7_time = UUID::getTime('061a3d43-61d0-7cf4-bfce-753dadab55e1');
195-
$this->assertSame($uuid7_time, '1638126646.1903860');
194+
$uuid7_time = UUID::getTime('061d0edc-bea0-75cc-9892-f6295fd7d295');
195+
$this->assertSame($uuid7_time, '1641082315.9141510');
196196
}
197197

198198
public function testGetTimeValid()

0 commit comments

Comments
 (0)