Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
Uuid
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
2 / 2
5
100.00% covered (success)
100.00%
1 / 1
 uuid
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 uuidBy
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Helpers;
6
7use Illuminate\Support\Str;
8use InvalidArgumentException;
9use Stringable;
10
11class Uuid
12{
13    /**
14     * Generate a v4 UUID
15     */
16    public static function uuid(): string
17    {
18        return sprintf(
19            '%08x-%04x-%04x-%04x-%012x',
20            mt_rand(0, 0xffffffff),
21            mt_rand(0, 0xffff),
22            // first bit is the uuid version, here 4
23            mt_rand(0, 0x0fff) | 0x4000,
24            // variant, here OSF DCE UUID
25            mt_rand(0, 0x3fff) | 0x8000,
26            mt_rand(0, 0xffffffffffff)
27        );
28    }
29
30    /**
31     * Generate a dependent v4 UUID
32     * @var string|int|float|Stringable $value any value that can be converted to string
33     */
34    public static function uuidBy(mixed $value, string $name = null): string
35    {
36        if (!is_null($name)) {
37            if (!preg_match('/^[\da-f]+$/i', $name)) {
38                throw new InvalidArgumentException('$name must be a hex string');
39            }
40
41            if (Str::length($name) > 20) {
42                throw new InvalidArgumentException('$name is longer than 20 characters');
43            }
44
45            $name = Str::lower($name);
46        }
47
48        $value = $name . md5((string) $value);
49
50        return sprintf(
51            '%08s-%04s-%04s-%04s-%012s',
52            Str::substr($value, 0, 8),
53            Str::substr($value, 8, 4),
54            // first bit is the uuid version, here 4
55            '4' . Str::substr($value, 13, 3),
56            // first bit is the variant (0x8-0xb), here OSF DCE UUID
57            dechex(8 + (hexdec(Str::substr($value, 16, 1)) % 4))
58            . Str::substr($value, 17, 3),
59            Str::substr($value, 20, 12)
60        );
61    }
62}