需要注意的 $twepoch 变量一定要在项目初始化时重置为当前最新时间
该方法 存在一定问题使用3年左右 会存在 - 符号
class SnowFlake { private static $lastTimestamp = 0; private static $lastSequence = 0; private static $sequenceMask = 4095;
private static $twepoch = 1715236393000;
static function randStr($length) { return substr(str_shuffle("abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ23456789"), 0, $length); }
static function randNumStr($length) { $chars = array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ); $password = ''; while (strlen($password) < $length) { $password .= $chars[rand(0, 9)]; } return $password; }
static function snowFlake() { $timestamp = self::timeGen();
if (self::$lastTimestamp == $timestamp) { self::$lastSequence = (self::$lastSequence + 1) & self::$sequenceMask; if (self::$lastSequence == 0) $timestamp = self::tilNextMillis(self::$lastTimestamp); } else { self::$lastSequence = 0; } self::$lastTimestamp = $timestamp;
$snowFlakeId = (($timestamp - self::$twepoch) << 27) | (getmypid() << 12) | self::$lastSequence;
return (string)$snowFlakeId; }
static function unSnowFlake($snowFlakeId) { $Binary = str_pad(decbin($snowFlakeId), 64, '0', STR_PAD_LEFT); return [ 'timestamp' => bindec(substr($Binary, 0, 41)) + self::$twepoch, 'dataCenterID' => bindec(substr($Binary, 42, 5)), 'workerID' => bindec(substr($Binary, 47, 5)), 'sequence' => bindec(substr($Binary, -12)), ]; }
private static function tilNextMillis($lastTimestamp) { $timestamp = self::timeGen(); while ($timestamp <= $lastTimestamp) { $timestamp = self::timeGen(); } return $timestamp; }
private static function timeGen() { return (float)sprintf('%.0f', microtime(true) * 1000); } }
|