|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Linna Framework. |
|
5
|
|
|
* |
|
6
|
|
|
* @author Sebastian Rapetti <[email protected]> |
|
7
|
|
|
* @copyright (c) 2018, Sebastian Rapetti |
|
8
|
|
|
* @license http://opensource.org/licenses/MIT MIT License |
|
9
|
|
|
*/ |
|
10
|
|
|
declare(strict_types=1); |
|
11
|
|
|
|
|
12
|
|
|
namespace Linna\DataMapper; |
|
13
|
|
|
|
|
14
|
|
|
use InvalidArgumentException; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* Universally Unique Identifier Version 4 utility. |
|
18
|
|
|
* https://en.wikipedia.org/wiki/Universally_unique_identifier |
|
19
|
|
|
* https://tools.ietf.org/html/rfc4122 |
|
20
|
|
|
* |
|
21
|
|
|
*/ |
|
22
|
|
|
class UUID4 |
|
23
|
|
|
{ |
|
24
|
|
|
/** |
|
25
|
|
|
* @var string UUID in hex form. |
|
26
|
|
|
*/ |
|
27
|
|
|
private $hexUUID = ''; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* @var string UUID in bin form. |
|
31
|
|
|
*/ |
|
32
|
|
|
private $binUUID = ''; |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* Constructor. |
|
36
|
|
|
*/ |
|
37
|
9 |
|
public function __construct(string $uuid = '') |
|
38
|
|
|
{ |
|
39
|
9 |
|
if (empty($uuid)) { |
|
40
|
6 |
|
$this->generate(); |
|
41
|
6 |
|
$this->makeBin(); |
|
42
|
|
|
|
|
43
|
6 |
|
return; |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
4 |
|
$this->check($uuid); |
|
47
|
3 |
|
$this->makeBin(); |
|
48
|
3 |
|
} |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* Check UUID. |
|
52
|
|
|
* |
|
53
|
|
|
* @param string $uuid |
|
54
|
|
|
* |
|
55
|
|
|
* @return void |
|
56
|
|
|
*/ |
|
57
|
4 |
|
private function check(string $uuid): void |
|
58
|
|
|
{ |
|
59
|
4 |
|
$uuid32 = str_replace('-', '', $uuid); |
|
60
|
|
|
|
|
61
|
4 |
|
if (preg_match('/^[0-9a-f]{8}[0-9a-f]{4}[4][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}$/i', $uuid32) !== 1) { |
|
62
|
1 |
|
throw new InvalidArgumentException('Invalid UUID version 4 provided.'); |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
3 |
|
$this->hexUUID = $uuid; |
|
66
|
3 |
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Get UUID in hex format (36 chars). |
|
70
|
|
|
* |
|
71
|
|
|
* @return string |
|
72
|
|
|
*/ |
|
73
|
6 |
|
public function getHex(): string |
|
74
|
|
|
{ |
|
75
|
6 |
|
return $this->hexUUID; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* Get UUID in binary format (16 byte). |
|
80
|
|
|
* |
|
81
|
|
|
* @return string |
|
82
|
|
|
*/ |
|
83
|
2 |
|
public function getBin(): string |
|
84
|
|
|
{ |
|
85
|
2 |
|
return $this->binUUID; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Return UUID in 16 byte binary format. |
|
90
|
|
|
* |
|
91
|
|
|
* @return string |
|
92
|
|
|
*/ |
|
93
|
8 |
|
private function makeBin(): void |
|
94
|
|
|
{ |
|
95
|
8 |
|
$this->binUUID = hex2bin(str_replace('-', '', $this->hexUUID)); |
|
96
|
8 |
|
} |
|
97
|
|
|
|
|
98
|
|
|
/** |
|
99
|
|
|
* Generate a random UUID v4 in hex format. |
|
100
|
|
|
* |
|
101
|
|
|
* @codeCoverageIgnore |
|
102
|
|
|
* |
|
103
|
|
|
* @return string |
|
104
|
|
|
*/ |
|
105
|
|
|
private function generate(): void |
|
106
|
|
|
{ |
|
107
|
|
|
$this->hexUUID = sprintf( |
|
108
|
|
|
'%s-%s-%s-%s-%s', |
|
109
|
|
|
// 8 hex characters |
|
110
|
|
|
bin2hex(random_bytes(4)), |
|
111
|
|
|
// 4 hex characters |
|
112
|
|
|
bin2hex(random_bytes(2)), |
|
113
|
|
|
// "4" for the UUID version + 3 hex characters |
|
114
|
|
|
// 0x4000 -> 16384 |
|
|
|
|
|
|
115
|
|
|
// 0x4fff -> 20479 |
|
|
|
|
|
|
116
|
|
|
dechex(random_int(16384, 20479)), |
|
117
|
|
|
// (8, 9, a, or b) for the UUID variant 1 plus 3 hex characters |
|
118
|
|
|
// 0x8000 -> 32768 |
|
|
|
|
|
|
119
|
|
|
// 0xbfff -> 49151 |
|
|
|
|
|
|
120
|
|
|
dechex(random_int(32768, 49151)), |
|
121
|
|
|
// 12 hex characters |
|
122
|
|
|
bin2hex(random_bytes(6)) |
|
123
|
|
|
); |
|
124
|
|
|
} |
|
125
|
|
|
} |
|
126
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.