Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
68.00% covered (warning)
68.00%
34 / 50
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Uuid
68.00% covered (warning)
68.00%
34 / 50
50.00% covered (danger)
50.00%
2 / 4
18.54
0.00% covered (danger)
0.00%
0 / 1
 generateGuid
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 isEqualGuid
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
5
 isGuid
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 adjustGuid
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
4.00
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\Core;
6
7use PeServer\Core\Throws\ArgumentException;
8
9abstract class Uuid
10{
11    #region function
12
13    /**
14     * GUID生成。
15     *
16     * 非Windows環境は謎の何か。
17     *
18     * @return string GUID文字列
19     */
20    public static function generateGuid(): string
21    {
22        if (function_exists('com_create_guid')) {
23            $guid = com_create_guid();
24            if ($guid !== false) {
25                return Text::trim($guid, '{}');
26            }
27        }
28
29        return sprintf(
30            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
31            Cryptography::generateRandomInteger(0, 65535),
32            Cryptography::generateRandomInteger(0, 65535),
33            Cryptography::generateRandomInteger(0, 65535),
34            Cryptography::generateRandomInteger(16384, 20479),
35            Cryptography::generateRandomInteger(32768, 49151),
36            Cryptography::generateRandomInteger(0, 65535),
37            Cryptography::generateRandomInteger(0, 65535),
38            Cryptography::generateRandomInteger(0, 65535)
39        );
40    }
41
42    /**
43     * GUIDとして同じか。
44     *
45     * @param string $a
46     * @param string $b
47     * @return bool
48     */
49    public static function isEqualGuid(string $a, string $b): bool
50    {
51        if ($a === $b) {
52            return true;
53        }
54
55        $a = Text::trim($a, '{}');
56        $b = Text::trim($b, '{}');
57
58        if ($a === $b) {
59            return true;
60        }
61
62        $a = Text::toLower($a);
63        $b = Text::toLower($b);
64
65        if ($a === $b) {
66            return true;
67        }
68
69        $a = Text::replace($a, '-', Text::EMPTY);
70        $b = Text::replace($b, '-', Text::EMPTY);
71
72        if ($a === $b) {
73            return true;
74        }
75
76        return false;
77    }
78
79    /**
80     * GUIDとして正しい書式か。
81     *
82     * 正確には正しくなくとも補正してGUIDとして扱えるか。
83     *
84     * @param string $value
85     * @return boolean
86     */
87    public static function isGuid(string $value): bool
88    {
89        $regex = new Regex();
90        return $regex->isMatch($value, '/^\{?[a-fA-F0-9]{8}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{4}-?[a-fA-F0-9]{12}\}?$/');
91    }
92
93    /**
94     * GUIDの文字列表現を統一。
95     *
96     * @param string $value
97     * @return string
98     * @throws ArgumentException 変換失敗。
99     */
100    public static function adjustGuid(string $value): string
101    {
102        if (Text::isNullOrWhiteSpace($value)) {
103            throw new ArgumentException();
104        }
105
106        $a = Text::trim($value, '{}');
107        $b = Text::replace($a, '-', Text::EMPTY);
108        if (Text::getLength($b) !== 32) {
109            throw new ArgumentException();
110        }
111        $c = Text::toLower($b);
112        $d = [
113            Text::substring($c, 0, 8),
114            Text::substring($c, 8, 4),
115            Text::substring($c, 8 + 4, 4),
116            Text::substring($c, 8 + 4 + 4, 4),
117            Text::substring($c, 8 + 4 + 4 + 4, 12),
118        ];
119        $e = Text::join('-', $d);
120
121        if (!self::isGuid($e)) {
122            throw new ArgumentException();
123        }
124
125        return $e;
126    }
127
128    #endregion
129}