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

Breadcrumb

  1. Drupal Core 11.1.x
  2. UnixTimeGenerator.php

function UnixTimeGenerator::increment

Special thanks to Nicolas Grekas for sharing the following information:

Within the same ms, we increment the rand part by a random 24-bit number.

Instead of getting this number from random_bytes(), which is slow, we get it by sha512-hashing self::$seed. This produces 64 bytes of entropy, which we need to split in a list of 24-bit numbers. unpack() first splits them into 16 x 32-bit numbers; we take the first byte of each of these numbers to get 5 extra 24-bit numbers. Then, we consume those numbers one-by-one and run this logic every 21 iterations.

self::$rand holds the random part of the UUID, split into 5 x 16-bit numbers for x86 portability. We increment this random part by the next 24-bit number in the self::$seedParts list and decrement self::$seedIndex.

@link https://twitter.com/nicolasgrekas/status/1583356938825261061 Tweet from Nicolas Grekas

1 call to UnixTimeGenerator::increment()
UnixTimeGenerator::generate in vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php
@inheritDoc

File

vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php, line 128

Class

UnixTimeGenerator
UnixTimeGenerator generates bytes that combine a 48-bit timestamp in milliseconds since the Unix Epoch with 80 random bits

Namespace

Ramsey\Uuid\Generator

Code

private function increment() : string {
    if (self::$seedIndex === 0 && self::$seed !== null) {
        self::$seed = hash('sha512', self::$seed, true);
        
        /** @var int[] $s */
        $s = unpack('l*', self::$seed);
        $s[] = $s[1] >> 8 & 0xff0000 | $s[2] >> 16 & 0xff00 | $s[3] >> 24 & 0xff;
        $s[] = $s[4] >> 8 & 0xff0000 | $s[5] >> 16 & 0xff00 | $s[6] >> 24 & 0xff;
        $s[] = $s[7] >> 8 & 0xff0000 | $s[8] >> 16 & 0xff00 | $s[9] >> 24 & 0xff;
        $s[] = $s[10] >> 8 & 0xff0000 | $s[11] >> 16 & 0xff00 | $s[12] >> 24 & 0xff;
        $s[] = $s[13] >> 8 & 0xff0000 | $s[14] >> 16 & 0xff00 | $s[15] >> 24 & 0xff;
        self::$seedParts = $s;
        self::$seedIndex = 21;
    }
    self::$rand[5] = 0xffff & ($carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xffffff));
    self::$rand[4] = 0xffff & ($carry = self::$rand[4] + ($carry >> 16));
    self::$rand[3] = 0xffff & ($carry = self::$rand[3] + ($carry >> 16));
    self::$rand[2] = 0xffff & ($carry = self::$rand[2] + ($carry >> 16));
    self::$rand[1] += $carry >> 16;
    if (0xfc00 & self::$rand[1]) {
        $time = self::$time;
        $mtime = (int) substr($time, -9);
        if ($this->intSize >= 8 || strlen($time) < 10) {
            $time = (string) ((int) $time + 1);
        }
        elseif ($mtime === 999999999) {
            $time = 1 + (int) substr($time, 0, -9) . '000000000';
        }
        else {
            $mtime++;
            $time = substr_replace($time, str_pad((string) $mtime, 9, '0', STR_PAD_LEFT), -9);
        }
        $this->randomize($time);
    }
    return self::$time;
}

API Navigation

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