Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x

DceSecurityGenerator.php

Namespace

Ramsey\Uuid\Generator

File

vendor/ramsey/uuid/src/Generator/DceSecurityGenerator.php

View source
<?php


/**
 * This file is part of the ramsey/uuid library
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
 * @license http://opensource.org/licenses/MIT MIT
 */
declare (strict_types=1);
namespace Ramsey\Uuid\Generator;

use Ramsey\Uuid\Converter\NumberConverterInterface;
use Ramsey\Uuid\Exception\DceSecurityException;
use Ramsey\Uuid\Provider\DceSecurityProviderInterface;
use Ramsey\Uuid\Type\Hexadecimal;
use Ramsey\Uuid\Type\Integer as IntegerObject;
use Ramsey\Uuid\Uuid;
use function hex2bin;
use function in_array;
use function pack;
use function str_pad;
use function strlen;
use function substr_replace;
use const STR_PAD_LEFT;

/**
 * DceSecurityGenerator generates strings of binary data based on a local
 * domain, local identifier, node ID, clock sequence, and the current time
 */
class DceSecurityGenerator implements DceSecurityGeneratorInterface {
    private const DOMAINS = [
        Uuid::DCE_DOMAIN_PERSON,
        Uuid::DCE_DOMAIN_GROUP,
        Uuid::DCE_DOMAIN_ORG,
    ];
    
    /**
     * Upper bounds for the clock sequence in DCE Security UUIDs.
     */
    private const CLOCK_SEQ_HIGH = 63;
    
    /**
     * Lower bounds for the clock sequence in DCE Security UUIDs.
     */
    private const CLOCK_SEQ_LOW = 0;
    public function __construct(NumberConverterInterface $numberConverter, TimeGeneratorInterface $timeGenerator, DceSecurityProviderInterface $dceSecurityProvider) {
    }
    public function generate(int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null) : string {
        if (!in_array($localDomain, self::DOMAINS)) {
            throw new DceSecurityException('Local domain must be a valid DCE Security domain');
        }
        if ($localIdentifier && $localIdentifier->isNegative()) {
            throw new DceSecurityException('Local identifier out of bounds; it must be a value between 0 and 4294967295');
        }
        if ($clockSeq > self::CLOCK_SEQ_HIGH || $clockSeq < self::CLOCK_SEQ_LOW) {
            throw new DceSecurityException('Clock sequence out of bounds; it must be a value between 0 and 63');
        }
        switch ($localDomain) {
            case Uuid::DCE_DOMAIN_ORG:
                if ($localIdentifier === null) {
                    throw new DceSecurityException('A local identifier must be provided for the org domain');
                }
                break;
            case Uuid::DCE_DOMAIN_PERSON:
                if ($localIdentifier === null) {
                    $localIdentifier = $this->dceSecurityProvider
                        ->getUid();
                }
                break;
            case Uuid::DCE_DOMAIN_GROUP:
            default:
                if ($localIdentifier === null) {
                    $localIdentifier = $this->dceSecurityProvider
                        ->getGid();
                }
                break;
        }
        $identifierHex = $this->numberConverter
            ->toHex($localIdentifier->toString());
        // The maximum value for the local identifier is 0xffffffff, or
        // 4294967295. This is 8 hexadecimal digits, so if the length of
        // hexadecimal digits is greater than 8, we know the value is greater
        // than 0xffffffff.
        if (strlen($identifierHex) > 8) {
            throw new DceSecurityException('Local identifier out of bounds; it must be a value between 0 and 4294967295');
        }
        $domainByte = pack('n', $localDomain)[1];
        $identifierBytes = (string) hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT));
        if ($node instanceof Hexadecimal) {
            $node = $node->toString();
        }
        // Shift the clock sequence 8 bits to the left, so it matches 0x3f00.
        if ($clockSeq !== null) {
            $clockSeq = $clockSeq << 8;
        }
        $bytes = $this->timeGenerator
            ->generate($node, $clockSeq);
        // Replace bytes in the time-based UUID with DCE Security values.
        $bytes = substr_replace($bytes, $identifierBytes, 0, 4);
        return substr_replace($bytes, $domainByte, 9, 1);
    }

}

Classes

Title Deprecated Summary
DceSecurityGenerator DceSecurityGenerator generates strings of binary data based on a local domain, local identifier, node ID, clock sequence, and the current time

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal