Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the ramsey/uuid library
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
10
 * @license http://opensource.org/licenses/MIT MIT
11
 */
12
 
13
declare(strict_types=1);
14
 
15
namespace Ramsey\Uuid;
16
 
17
use BadMethodCallException;
18
use DateTimeInterface;
19
use Ramsey\Uuid\Codec\CodecInterface;
20
use Ramsey\Uuid\Converter\NumberConverterInterface;
21
use Ramsey\Uuid\Converter\TimeConverterInterface;
22
use Ramsey\Uuid\Exception\UnsupportedOperationException;
23
use Ramsey\Uuid\Fields\FieldsInterface;
24
use Ramsey\Uuid\Lazy\LazyUuidFromString;
25
use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface;
26
use Ramsey\Uuid\Type\Hexadecimal;
27
use Ramsey\Uuid\Type\Integer as IntegerObject;
28
use ValueError;
29
 
30
use function assert;
31
use function bin2hex;
32
use function method_exists;
33
use function preg_match;
34
use function sprintf;
35
use function str_replace;
36
use function strcmp;
37
use function strlen;
38
use function strtolower;
39
use function substr;
40
 
41
/**
42
 * Uuid provides constants and static methods for working with and generating UUIDs
43
 *
44
 * @psalm-immutable
45
 */
46
class Uuid implements UuidInterface
47
{
48
    use DeprecatedUuidMethodsTrait;
49
 
50
    /**
51
     * When this namespace is specified, the name string is a fully-qualified
52
     * domain name
53
     *
54
     * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
55
     */
56
    public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
57
 
58
    /**
59
     * When this namespace is specified, the name string is a URL
60
     *
61
     * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
62
     */
63
    public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
64
 
65
    /**
66
     * When this namespace is specified, the name string is an ISO OID
67
     *
68
     * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
69
     */
70
    public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8';
71
 
72
    /**
73
     * When this namespace is specified, the name string is an X.500 DN in DER
74
     * or a text output format
75
     *
76
     * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs
77
     */
78
    public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8';
79
 
80
    /**
81
     * The nil UUID is a special form of UUID that is specified to have all 128
82
     * bits set to zero
83
     *
84
     * @link http://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID
85
     */
86
    public const NIL = '00000000-0000-0000-0000-000000000000';
87
 
88
    /**
89
     * The max UUID is a special form of UUID that is specified to have all 128
90
     * bits set to one
91
     *
92
     * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID
93
     */
94
    public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff';
95
 
96
    /**
97
     * Variant: reserved, NCS backward compatibility
98
     *
99
     * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
100
     */
101
    public const RESERVED_NCS = 0;
102
 
103
    /**
104
     * Variant: the UUID layout specified in RFC 4122
105
     *
106
     * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
107
     */
108
    public const RFC_4122 = 2;
109
 
110
    /**
111
     * Variant: reserved, Microsoft Corporation backward compatibility
112
     *
113
     * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
114
     */
115
    public const RESERVED_MICROSOFT = 6;
116
 
117
    /**
118
     * Variant: reserved for future definition
119
     *
120
     * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant
121
     */
122
    public const RESERVED_FUTURE = 7;
123
 
124
    /**
125
     * @deprecated Use {@see ValidatorInterface::getPattern()} instead.
126
     */
127
    public const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$';
128
 
129
    /**
130
     * Version 1 (Gregorian time) UUID
131
     *
132
     * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
133
     */
134
    public const UUID_TYPE_TIME = 1;
135
 
136
    /**
137
     * Version 2 (DCE Security) UUID
138
     *
139
     * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
140
     */
141
    public const UUID_TYPE_DCE_SECURITY = 2;
142
 
143
    /**
144
     * @deprecated Use {@see Uuid::UUID_TYPE_DCE_SECURITY} instead.
145
     */
146
    public const UUID_TYPE_IDENTIFIER = 2;
147
 
148
    /**
149
     * Version 3 (name-based and hashed with MD5) UUID
150
     *
151
     * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
152
     */
153
    public const UUID_TYPE_HASH_MD5 = 3;
154
 
155
    /**
156
     * Version 4 (random) UUID
157
     *
158
     * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
159
     */
160
    public const UUID_TYPE_RANDOM = 4;
161
 
162
    /**
163
     * Version 5 (name-based and hashed with SHA1) UUID
164
     *
165
     * @link https://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version
166
     */
167
    public const UUID_TYPE_HASH_SHA1 = 5;
168
 
169
    /**
170
     * @deprecated Use {@see Uuid::UUID_TYPE_REORDERED_TIME} instead.
171
     */
172
    public const UUID_TYPE_PEABODY = 6;
173
 
174
    /**
175
     * Version 6 (reordered time) UUID
176
     *
177
     * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6
178
     */
179
    public const UUID_TYPE_REORDERED_TIME = 6;
180
 
181
    /**
182
     * Version 7 (Unix Epoch time) UUID
183
     *
184
     * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7
185
     */
186
    public const UUID_TYPE_UNIX_TIME = 7;
187
 
188
    /**
189
     * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8
190
     */
191
    public const UUID_TYPE_CUSTOM = 8;
192
 
193
    /**
194
     * DCE Security principal domain
195
     *
196
     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
197
     */
198
    public const DCE_DOMAIN_PERSON = 0;
199
 
200
    /**
201
     * DCE Security group domain
202
     *
203
     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
204
     */
205
    public const DCE_DOMAIN_GROUP = 1;
206
 
207
    /**
208
     * DCE Security organization domain
209
     *
210
     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
211
     */
212
    public const DCE_DOMAIN_ORG = 2;
213
 
214
    /**
215
     * DCE Security domain string names
216
     *
217
     * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1
218
     */
219
    public const DCE_DOMAIN_NAMES = [
220
        self::DCE_DOMAIN_PERSON => 'person',
221
        self::DCE_DOMAIN_GROUP => 'group',
222
        self::DCE_DOMAIN_ORG => 'org',
223
    ];
224
 
225
    private static ?UuidFactoryInterface $factory = null;
226
 
227
    /**
228
     * @var bool flag to detect if the UUID factory was replaced internally,
229
     *     which disables all optimizations for the default/happy path internal
230
     *     scenarios
231
     */
232
    private static bool $factoryReplaced = false;
233
 
234
    protected CodecInterface $codec;
235
    protected NumberConverterInterface $numberConverter;
236
    protected Rfc4122FieldsInterface $fields;
237
    protected TimeConverterInterface $timeConverter;
238
 
239
    /**
240
     * Creates a universally unique identifier (UUID) from an array of fields
241
     *
242
     * Unless you're making advanced use of this library to generate identifiers
243
     * that deviate from RFC 4122, you probably do not want to instantiate a
244
     * UUID directly. Use the static methods, instead:
245
     *
246
     * ```
247
     * use Ramsey\Uuid\Uuid;
248
     *
249
     * $timeBasedUuid = Uuid::uuid1();
250
     * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/');
251
     * $randomUuid = Uuid::uuid4();
252
     * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/');
253
     * ```
254
     *
255
     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID
256
     * @param NumberConverterInterface $numberConverter The number converter to use
257
     *     for converting hex values to/from integers
258
     * @param CodecInterface $codec The codec to use when encoding or decoding
259
     *     UUID strings
260
     * @param TimeConverterInterface $timeConverter The time converter to use
261
     *     for converting timestamps extracted from a UUID to unix timestamps
262
     */
263
    public function __construct(
264
        Rfc4122FieldsInterface $fields,
265
        NumberConverterInterface $numberConverter,
266
        CodecInterface $codec,
267
        TimeConverterInterface $timeConverter
268
    ) {
269
        $this->fields = $fields;
270
        $this->codec = $codec;
271
        $this->numberConverter = $numberConverter;
272
        $this->timeConverter = $timeConverter;
273
    }
274
 
275
    /**
276
     * @psalm-return non-empty-string
277
     */
278
    public function __toString(): string
279
    {
280
        return $this->toString();
281
    }
282
 
283
    /**
284
     * Converts the UUID to a string for JSON serialization
285
     */
286
    public function jsonSerialize(): string
287
    {
288
        return $this->toString();
289
    }
290
 
291
    /**
292
     * Converts the UUID to a string for PHP serialization
293
     */
294
    public function serialize(): string
295
    {
296
        return $this->getFields()->getBytes();
297
    }
298
 
299
    /**
300
     * @return array{bytes: string}
301
     */
302
    public function __serialize(): array
303
    {
304
        return ['bytes' => $this->serialize()];
305
    }
306
 
307
    /**
308
     * Re-constructs the object from its serialized form
309
     *
310
     * @param string $data The serialized PHP string to unserialize into
311
     *     a UuidInterface instance
312
     */
313
    public function unserialize(string $data): void
314
    {
315
        if (strlen($data) === 16) {
316
            /** @var Uuid $uuid */
317
            $uuid = self::getFactory()->fromBytes($data);
318
        } else {
319
            /** @var Uuid $uuid */
320
            $uuid = self::getFactory()->fromString($data);
321
        }
322
 
323
        $this->codec = $uuid->codec;
324
        $this->numberConverter = $uuid->numberConverter;
325
        $this->fields = $uuid->fields;
326
        $this->timeConverter = $uuid->timeConverter;
327
    }
328
 
329
    /**
330
     * @param array{bytes?: string} $data
331
     */
332
    public function __unserialize(array $data): void
333
    {
334
        // @codeCoverageIgnoreStart
335
        if (!isset($data['bytes'])) {
336
            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));
337
        }
338
        // @codeCoverageIgnoreEnd
339
 
340
        $this->unserialize($data['bytes']);
341
    }
342
 
343
    public function compareTo(UuidInterface $other): int
344
    {
345
        $compare = strcmp($this->toString(), $other->toString());
346
 
347
        if ($compare < 0) {
348
            return -1;
349
        }
350
 
351
        if ($compare > 0) {
352
            return 1;
353
        }
354
 
355
        return 0;
356
    }
357
 
358
    public function equals(?object $other): bool
359
    {
360
        if (!$other instanceof UuidInterface) {
361
            return false;
362
        }
363
 
364
        return $this->compareTo($other) === 0;
365
    }
366
 
367
    /**
368
     * @psalm-return non-empty-string
369
     */
370
    public function getBytes(): string
371
    {
372
        return $this->codec->encodeBinary($this);
373
    }
374
 
375
    public function getFields(): FieldsInterface
376
    {
377
        return $this->fields;
378
    }
379
 
380
    public function getHex(): Hexadecimal
381
    {
382
        return new Hexadecimal(str_replace('-', '', $this->toString()));
383
    }
384
 
385
    public function getInteger(): IntegerObject
386
    {
387
        return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString()));
388
    }
389
 
390
    public function getUrn(): string
391
    {
392
        return 'urn:uuid:' . $this->toString();
393
    }
394
 
395
    /**
396
     * @psalm-return non-empty-string
397
     */
398
    public function toString(): string
399
    {
400
        return $this->codec->encode($this);
401
    }
402
 
403
    /**
404
     * Returns the factory used to create UUIDs
405
     */
406
    public static function getFactory(): UuidFactoryInterface
407
    {
408
        if (self::$factory === null) {
409
            self::$factory = new UuidFactory();
410
        }
411
 
412
        return self::$factory;
413
    }
414
 
415
    /**
416
     * Sets the factory used to create UUIDs
417
     *
418
     * @param UuidFactoryInterface $factory A factory that will be used by this
419
     *     class to create UUIDs
420
     */
421
    public static function setFactory(UuidFactoryInterface $factory): void
422
    {
423
        // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption
424
        //       around purity is broken, and we have to internally decide everything differently.
425
        // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator
426
        self::$factoryReplaced = ($factory != new UuidFactory());
427
 
428
        self::$factory = $factory;
429
    }
430
 
431
    /**
432
     * Creates a UUID from a byte string
433
     *
434
     * @param string $bytes A binary string
435
     *
436
     * @return UuidInterface A UuidInterface instance created from a binary
437
     *     string representation
438
     *
439
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
440
     *             but under constant factory setups, this method operates in functionally pure manners
441
     *
442
     * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive
443
     *                                      havoc across all consumers: that should never happen, and
444
     *                                      is generally to be discouraged. Until the factory is kept
445
     *                                      un-replaced, this method is effectively pure.
446
     */
447
    public static function fromBytes(string $bytes): UuidInterface
448
    {
449
        if (! self::$factoryReplaced && strlen($bytes) === 16) {
450
            $base16Uuid = bin2hex($bytes);
451
 
452
            // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID
453
            return self::fromString(
454
                substr($base16Uuid, 0, 8)
455
                . '-'
456
                . substr($base16Uuid, 8, 4)
457
                . '-'
458
                . substr($base16Uuid, 12, 4)
459
                . '-'
460
                . substr($base16Uuid, 16, 4)
461
                . '-'
462
                . substr($base16Uuid, 20, 12)
463
            );
464
        }
465
 
466
        return self::getFactory()->fromBytes($bytes);
467
    }
468
 
469
    /**
470
     * Creates a UUID from the string standard representation
471
     *
472
     * @param string $uuid A hexadecimal string
473
     *
474
     * @return UuidInterface A UuidInterface instance created from a hexadecimal
475
     *     string representation
476
     *
477
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
478
     *             but under constant factory setups, this method operates in functionally pure manners
479
     *
480
     * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive
481
     *                                      havoc across all consumers: that should never happen, and
482
     *                                      is generally to be discouraged. Until the factory is kept
483
     *                                      un-replaced, this method is effectively pure.
484
     */
485
    public static function fromString(string $uuid): UuidInterface
486
    {
487
        $uuid = strtolower($uuid);
488
        if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) {
489
            assert($uuid !== '');
490
 
491
            return new LazyUuidFromString($uuid);
492
        }
493
 
494
        return self::getFactory()->fromString($uuid);
495
    }
496
 
497
    /**
498
     * Creates a UUID from a DateTimeInterface instance
499
     *
500
     * @param DateTimeInterface $dateTime The date and time
501
     * @param Hexadecimal|null $node A 48-bit number representing the hardware
502
     *     address
503
     * @param int|null $clockSeq A 14-bit number used to help avoid duplicates
504
     *     that could arise when the clock is set backwards in time or if the
505
     *     node ID changes
506
     *
507
     * @return UuidInterface A UuidInterface instance that represents a
508
     *     version 1 UUID created from a DateTimeInterface instance
509
     */
510
    public static function fromDateTime(
511
        DateTimeInterface $dateTime,
512
        ?Hexadecimal $node = null,
513
        ?int $clockSeq = null
514
    ): UuidInterface {
515
        return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq);
516
    }
517
 
518
    /**
519
     * Creates a UUID from the Hexadecimal object
520
     *
521
     * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number
522
     *
523
     * @return UuidInterface A UuidInterface instance created from the Hexadecimal
524
     * object representing a hexadecimal number
525
     *
526
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
527
     *             but under constant factory setups, this method operates in functionally pure manners
528
     * @psalm-suppress MixedInferredReturnType,MixedReturnStatement
529
     */
530
    public static function fromHexadecimal(Hexadecimal $hex): UuidInterface
531
    {
532
        $factory = self::getFactory();
533
 
534
        if (method_exists($factory, 'fromHexadecimal')) {
535
            /**
536
             * @phpstan-ignore-next-line
537
             * @psalm-suppress UndefinedInterfaceMethod
538
             */
539
            return self::getFactory()->fromHexadecimal($hex);
540
        }
541
 
542
        throw new BadMethodCallException('The method fromHexadecimal() does not exist on the provided factory');
543
    }
544
 
545
    /**
546
     * Creates a UUID from a 128-bit integer string
547
     *
548
     * @param string $integer String representation of 128-bit integer
549
     *
550
     * @return UuidInterface A UuidInterface instance created from the string
551
     *     representation of a 128-bit integer
552
     *
553
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
554
     *             but under constant factory setups, this method operates in functionally pure manners
555
     */
556
    public static function fromInteger(string $integer): UuidInterface
557
    {
558
        /** @psalm-suppress ImpureMethodCall */
559
        return self::getFactory()->fromInteger($integer);
560
    }
561
 
562
    /**
563
     * Returns true if the provided string is a valid UUID
564
     *
565
     * @param string $uuid A string to validate as a UUID
566
     *
567
     * @return bool True if the string is a valid UUID, false otherwise
568
     *
569
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
570
     *             but under constant factory setups, this method operates in functionally pure manners
571
     *
572
     * @psalm-assert-if-true =non-empty-string $uuid
573
     */
574
    public static function isValid(string $uuid): bool
575
    {
576
        /** @psalm-suppress ImpureMethodCall */
577
        return self::getFactory()->getValidator()->validate($uuid);
578
    }
579
 
580
    /**
581
     * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number,
582
     * and the current time
583
     *
584
     * @param Hexadecimal|int|string|null $node A 48-bit number representing the
585
     *     hardware address; this number may be represented as an integer or a
586
     *     hexadecimal string
587
     * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that
588
     *     could arise when the clock is set backwards in time or if the node ID
589
     *     changes
590
     *
591
     * @return UuidInterface A UuidInterface instance that represents a
592
     *     version 1 UUID
593
     */
594
    public static function uuid1($node = null, ?int $clockSeq = null): UuidInterface
595
    {
596
        return self::getFactory()->uuid1($node, $clockSeq);
597
    }
598
 
599
    /**
600
     * Returns a version 2 (DCE Security) UUID from a local domain, local
601
     * identifier, host ID, clock sequence, and the current time
602
     *
603
     * @param int $localDomain The local domain to use when generating bytes,
604
     *     according to DCE Security
605
     * @param IntegerObject|null $localIdentifier The local identifier for the
606
     *     given domain; this may be a UID or GID on POSIX systems, if the local
607
     *     domain is person or group, or it may be a site-defined identifier
608
     *     if the local domain is org
609
     * @param Hexadecimal|null $node A 48-bit number representing the hardware
610
     *     address
611
     * @param int|null $clockSeq A 14-bit number used to help avoid duplicates
612
     *     that could arise when the clock is set backwards in time or if the
613
     *     node ID changes (in a version 2 UUID, the lower 8 bits of this number
614
     *     are replaced with the domain).
615
     *
616
     * @return UuidInterface A UuidInterface instance that represents a
617
     *     version 2 UUID
618
     */
619
    public static function uuid2(
620
        int $localDomain,
621
        ?IntegerObject $localIdentifier = null,
622
        ?Hexadecimal $node = null,
623
        ?int $clockSeq = null
624
    ): UuidInterface {
625
        return self::getFactory()->uuid2($localDomain, $localIdentifier, $node, $clockSeq);
626
    }
627
 
628
    /**
629
     * Returns a version 3 (name-based) UUID based on the MD5 hash of a
630
     * namespace ID and a name
631
     *
632
     * @param string|UuidInterface $ns The namespace (must be a valid UUID)
633
     * @param string $name The name to use for creating a UUID
634
     *
635
     * @return UuidInterface A UuidInterface instance that represents a
636
     *     version 3 UUID
637
     *
638
     * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive
639
     *                                  havoc across all consumers: that should never happen, and
640
     *                                  is generally to be discouraged. Until the factory is kept
641
     *                                  un-replaced, this method is effectively pure.
642
     *
643
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
644
     *             but under constant factory setups, this method operates in functionally pure manners
645
     */
646
    public static function uuid3($ns, string $name): UuidInterface
647
    {
648
        return self::getFactory()->uuid3($ns, $name);
649
    }
650
 
651
    /**
652
     * Returns a version 4 (random) UUID
653
     *
654
     * @return UuidInterface A UuidInterface instance that represents a
655
     *     version 4 UUID
656
     */
657
    public static function uuid4(): UuidInterface
658
    {
659
        return self::getFactory()->uuid4();
660
    }
661
 
662
    /**
663
     * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a
664
     * namespace ID and a name
665
     *
666
     * @param string|UuidInterface $ns The namespace (must be a valid UUID)
667
     * @param string $name The name to use for creating a UUID
668
     *
669
     * @return UuidInterface A UuidInterface instance that represents a
670
     *     version 5 UUID
671
     *
672
     * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants,
673
     *             but under constant factory setups, this method operates in functionally pure manners
674
     *
675
     * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive
676
     *                                  havoc across all consumers: that should never happen, and
677
     *                                  is generally to be discouraged. Until the factory is kept
678
     *                                  un-replaced, this method is effectively pure.
679
     */
680
    public static function uuid5($ns, string $name): UuidInterface
681
    {
682
        return self::getFactory()->uuid5($ns, $name);
683
    }
684
 
685
    /**
686
     * Returns a version 6 (reordered time) UUID from a host ID, sequence number,
687
     * and the current time
688
     *
689
     * @param Hexadecimal|null $node A 48-bit number representing the hardware
690
     *     address
691
     * @param int|null $clockSeq A 14-bit number used to help avoid duplicates that
692
     *     could arise when the clock is set backwards in time or if the node ID
693
     *     changes
694
     *
695
     * @return UuidInterface A UuidInterface instance that represents a
696
     *     version 6 UUID
697
     */
698
    public static function uuid6(
699
        ?Hexadecimal $node = null,
700
        ?int $clockSeq = null
701
    ): UuidInterface {
702
        return self::getFactory()->uuid6($node, $clockSeq);
703
    }
704
 
705
    /**
706
     * Returns a version 7 (Unix Epoch time) UUID
707
     *
708
     * @param DateTimeInterface|null $dateTime An optional date/time from which
709
     *     to create the version 7 UUID. If not provided, the UUID is generated
710
     *     using the current date/time.
711
     *
712
     * @return UuidInterface A UuidInterface instance that represents a
713
     *     version 7 UUID
714
     */
715
    public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface
716
    {
717
        $factory = self::getFactory();
718
 
719
        if (method_exists($factory, 'uuid7')) {
720
            /** @var UuidInterface */
721
            return $factory->uuid7($dateTime);
722
        }
723
 
724
        throw new UnsupportedOperationException(
725
            'The provided factory does not support the uuid7() method',
726
        );
727
    }
728
 
729
    /**
730
     * Returns a version 8 (custom) UUID
731
     *
732
     * The bytes provided may contain any value according to your application's
733
     * needs. Be aware, however, that other applications may not understand the
734
     * semantics of the value.
735
     *
736
     * @param string $bytes A 16-byte octet string. This is an open blob
737
     *     of data that you may fill with 128 bits of information. Be aware,
738
     *     however, bits 48 through 51 will be replaced with the UUID version
739
     *     field, and bits 64 and 65 will be replaced with the UUID variant. You
740
     *     MUST NOT rely on these bits for your application needs.
741
     *
742
     * @return UuidInterface A UuidInterface instance that represents a
743
     *     version 8 UUID
744
     */
745
    public static function uuid8(string $bytes): UuidInterface
746
    {
747
        $factory = self::getFactory();
748
 
749
        if (method_exists($factory, 'uuid8')) {
750
            /** @var UuidInterface */
751
            return $factory->uuid8($bytes);
752
        }
753
 
754
        throw new UnsupportedOperationException(
755
            'The provided factory does not support the uuid8() method',
756
        );
757
    }
758
}