static function generate(int $workerID = 1, int $processID = 0) {
        if($workerID > 31 || $workerID < 0) {
            throw new \InvalidArgumentException('Worker ID is out of range');
        }
        
        if($processID > 31 || $processID < 0) {
            throw new \InvalidArgumentException('Process ID is out of range');
        }
        
        $time = \microtime(true);
        
        if($time === static::$incrementTime) {
            static::$incrementIndex++;
            
            if(static::$incrementIndex >= 4095) {
                \usleep(1000);
                
                $time = \microtime(true);
                static::$incrementIndex = 0;
            }
        } else {
            static::$incrementIndex = 0;
            static::$incrementTime = $time;
        }
        
        $workerID = \str_pad(\decbin($workerID), 5, 0, \STR_PAD_LEFT);
        $processID = \str_pad(\decbin($processID), 5, 0, \STR_PAD_LEFT);
        
        $mtime = \explode('.', ((string) $time));
        if(\count($mtime) < 2) {
            $mtime[1] = '000';
        }
        
        $time = ((string) (((int) $mtime[0]) - static::EPOCH)).\substr($mtime[1], 0, 3);
        
        if(\PHP_INT_SIZE === 4) {
            $binary = \str_pad(\base_convert($time, 10, 2), 42, 0, \STR_PAD_LEFT).$workerID.$processID.\str_pad(\decbin(static::$incrementIndex), 12, 0, \STR_PAD_LEFT);
            return \base_convert($binary, 2, 10);
        } else {
            $binary = \str_pad(\decbin(((int) $time)), 42, 0, \STR_PAD_LEFT).$workerID.$processID.\str_pad(\decbin(static::$incrementIndex), 12, 0, \STR_PAD_LEFT);
            return ((string) \bindec($binary));
        }
    }