protected static function mintTime($node = NULL, $seq = NULL, $time = NULL) { /* Generates a Version 1 UUID. These are derived from the time at which they were generated. */ // Do a sanity check on clock sequence if ($seq !== NULL && strlen($seq) != 2) { throw UUIDException("Clock sequence most be a two-byte binary string."); } // If no time is specified, get time since Gregorian calendar // reform in 100ns intervals. This is exceedingly difficult // because of PHP's (and pack()'s) integer size limits // Note that this will never be more accurate than to the microsecond // Specifying a time for this method should only ever be used for // debugging purposes, lest uniqueness be compromised $time = $time !== NULL ? (double) $time : microtime(1); $time = $time * 10000000 + self::interval; // Convert to a string representation $time = sprintf("%F", $time); preg_match("/^\\d+/", $time, $time); //strip decimal point // And now to a 64-bit binary representation $time = base_convert($time[0], 10, 16); $time = pack("H*", str_pad($time, 16, "0", STR_PAD_LEFT)); // Reorder bytes to their proper locations in the UUID $uuid = $time[4] . $time[5] . $time[6] . $time[7] . $time[2] . $time[3] . $time[0] . $time[1]; // Generate a random clock sequence if one is not provided // Please consult Sections 4.1.5 and 4.2.1 of RFC 4122 for // guidance regarding when to use a new clock sequence $uuid .= $seq !== NULL ? $seq : self::randomBytes(2); // set variant $uuid[8] = chr(ord($uuid[8]) & self::clearVar | self::varRFC); // set version $uuid[6] = chr(ord($uuid[6]) & self::clearVer | self::version1); // Set the final 'node' parameter, a MAC address if ($node) { $node = self::makeBin($node, 6); } if (!$node) { // If no node was provided or if the node was invalid, // generate a random MAC address and set the multicast bit $node = self::randomBytes(6); $node[0] = pack("C", ord($node[0]) | 1); } $uuid .= $node; return $uuid; }
protected static function CheckTimeInput($node, $seq, $time) { /* If no timestamp has been specified, generate one. Note that this will never be more accurate than to the microsecond, whereas UUID timestamps are measured in 100ns steps. */ $time = $time !== NULL ? self::normalizeTime($time) : self::normalizeTime(microtime(), 1); /* If a node ID is supplied, use it and keep it in the store; if none is supplied, get it from the store or generate it if none is stored. */ if ($node === NULL) { $node = self::$store->getNode(); if (!$node) { $node = self::randomBytes(6); $node[0] = pack("C", ord($node[0]) | 1); } } else { $node = self::makeNode($node); if (!$node) { throw new UUIDException("Node must be a valid MAC address.", 101); } } // Do a sanity check on clock sequence if one is provided if ($seq !== NULL && strlen($seq) != 2) { throw UUIDException("Clock sequence must be a two-byte binary string.", 102); } // If one is not provided, check stable/volatile storage for a valid clock sequence if ($seq === NULL) { $seq = self::$store->getSequence($time, $node); } // Generate a random clock sequence if one is not available if (!$seq) { $seq = self::seq(); self::$store->setSequence($seq); } self::$store->setTimestamp($time); return array($node, $seq, $time); }