PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.6.2
Defender Security – Malware Scanner, Login Security & Firewall v5.6.2
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / vendor / ramsey / uuid / src / Uuid.php

Uuid.php in Defender Security – Malware Scanner, Login Security & Firewall 5.6.2, at vendor/ramsey/uuid/src/Uuid.php

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