This repository was archived by the owner on Mar 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathUUID.php
More file actions
132 lines (110 loc) · 3.81 KB
/
Copy pathUUID.php
File metadata and controls
132 lines (110 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\uuid;
use pocketmine\utils\Binary;
use function bin2hex;
use function getmypid;
use function getmyuid;
use function hash;
use function hex2bin;
use function implode;
use function mt_rand;
use function str_replace;
use function strlen;
use function substr;
use function time;
use function trim;
final class UUID{
/** @var int[] */
private $parts;
/** @var int */
private $version;
public function __construct(int $part1 = 0, int $part2 = 0, int $part3 = 0, int $part4 = 0, ?int $version = null){
$this->parts = [$part1, $part2, $part3, $part4];
$this->version = $version ?? ($this->parts[1] & 0xf000) >> 12;
}
public function getVersion() : int{
return $this->version;
}
public function equals(UUID $uuid) : bool{
return $uuid->parts === $this->parts;
}
/**
* Creates an UUID from an hexadecimal representation
*/
public static function fromString(string $uuid, ?int $version = null) : UUID{
//TODO: should we be stricter about the notation (8-4-4-4-12)?
$binary = @hex2bin(str_replace("-", "", trim($uuid)));
if($binary === false){
throw new \InvalidArgumentException("Invalid hex string UUID representation");
}
return self::fromBinary($binary, $version);
}
/**
* Creates an UUID from a binary representation
*
* @throws \InvalidArgumentException
*/
public static function fromBinary(string $uuid, ?int $version = null) : UUID{
if(strlen($uuid) !== 16){
throw new \InvalidArgumentException("Must have exactly 16 bytes");
}
return new UUID(Binary::readInt(substr($uuid, 0, 4)), Binary::readInt(substr($uuid, 4, 4)), Binary::readInt(substr($uuid, 8, 4)), Binary::readInt(substr($uuid, 12, 4)), $version);
}
/**
* Creates an UUIDv3 from binary data or list of binary data
*
* @param string ...$data
*/
public static function fromData(string ...$data) : UUID{
$hash = hash("md5", implode($data), true);
return self::fromBinary($hash, 3);
}
public static function fromRandom() : UUID{
return self::fromData(Binary::writeInt(time()), Binary::writeShort(($pid = getmypid()) !== false ? $pid : 0), Binary::writeShort(($uid = getmyuid()) !== false ? $uid : 0), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)), Binary::writeInt(mt_rand(-0x7fffffff, 0x7fffffff)));
}
public function toBinary() : string{
return Binary::writeInt($this->parts[0]) . Binary::writeInt($this->parts[1]) . Binary::writeInt($this->parts[2]) . Binary::writeInt($this->parts[3]);
}
public function toString() : string{
$hex = bin2hex($this->toBinary());
//xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 8-4-4-4-12
return substr($hex, 0, 8) . "-" . substr($hex, 8, 4) . "-" . substr($hex, 12, 4) . "-" . substr($hex, 16, 4) . "-" . substr($hex, 20, 12);
}
public function __toString() : string{
return $this->toString();
}
/**
* @throws \InvalidArgumentException
*/
public function getPart(int $partNumber) : int{
if($partNumber < 0 or $partNumber > 3){
throw new \InvalidArgumentException("Invalid UUID part index $partNumber");
}
return $this->parts[$partNumber];
}
/**
* @return int[]
*/
public function getParts() : array{
return $this->parts;
}
}