Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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 <ben@benramsey.com>
10
 * @license http://opensource.org/licenses/MIT MIT
11
 */
12
 
13
declare(strict_types=1);
14
 
15
namespace Ramsey\Uuid\Generator;
16
 
17
use Ramsey\Uuid\Converter\NumberConverterInterface;
18
use Ramsey\Uuid\Exception\InvalidArgumentException;
19
 
20
use function bin2hex;
21
use function explode;
22
use function hex2bin;
23
use function microtime;
24
use function str_pad;
25
use function substr;
26
 
27
use const STR_PAD_LEFT;
28
 
29
/**
30
 * CombGenerator generates COMBs (combined UUID/timestamp)
31
 *
32
 * The CombGenerator, when used with the StringCodec (and, by proxy, the
33
 * TimestampLastCombCodec) or the TimestampFirstCombCodec, combines the current
34
 * timestamp with a UUID (hence the name "COMB"). The timestamp either appears
35
 * as the first or last 48 bits of the COMB, depending on the codec used.
36
 *
37
 * By default, COMBs will have the timestamp set as the last 48 bits of the
38
 * identifier.
39
 *
40
 * ``` php
41
 * $factory = new UuidFactory();
42
 *
43
 * $factory->setRandomGenerator(new CombGenerator(
44
 *     $factory->getRandomGenerator(),
45
 *     $factory->getNumberConverter()
46
 * ));
47
 *
48
 * $comb = $factory->uuid4();
49
 * ```
50
 *
51
 * To generate a COMB with the timestamp as the first 48 bits, set the
52
 * TimestampFirstCombCodec as the codec.
53
 *
54
 * ``` php
55
 * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder()));
56
 * ```
57
 *
58
 * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys
59
 */
60
class CombGenerator implements RandomGeneratorInterface
61
{
62
    public const TIMESTAMP_BYTES = 6;
63
 
64
    public function __construct(
65
        private RandomGeneratorInterface $generator,
66
        private NumberConverterInterface $numberConverter
67
    ) {
68
    }
69
 
70
    /**
71
     * @throws InvalidArgumentException if $length is not a positive integer
72
     *     greater than or equal to CombGenerator::TIMESTAMP_BYTES
73
     *
74
     * @inheritDoc
75
     */
76
    public function generate(int $length): string
77
    {
78
        if ($length < self::TIMESTAMP_BYTES) {
79
            throw new InvalidArgumentException(
80
                'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES
81
            );
82
        }
83
 
84
        $hash = '';
85
        if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) {
86
            $hash = $this->generator->generate($length - self::TIMESTAMP_BYTES);
87
        }
88
 
89
        $lsbTime = str_pad(
90
            $this->numberConverter->toHex($this->timestamp()),
91
            self::TIMESTAMP_BYTES * 2,
92
            '0',
93
            STR_PAD_LEFT
94
        );
95
 
96
        return (string) hex2bin(
97
            str_pad(
98
                bin2hex($hash),
99
                $length - self::TIMESTAMP_BYTES,
100
                '0'
101
            )
102
            . $lsbTime
103
        );
104
    }
105
 
106
    /**
107
     * Returns current timestamp a string integer, precise to 0.00001 seconds
108
     */
109
    private function timestamp(): string
110
    {
111
        $time = explode(' ', microtime(false));
112
 
113
        return $time[1] . substr($time[0], 2, 5);
114
    }
115
}