PHP使用SnowFlake算法生成唯一ID
来源:互联网 发布:linux shell 参数 编辑:程序博客网 时间:2024/05/17 07:18
namespace App\Services;abstract class Particle { const EPOCH = 1479533469598; const max12bit = 4095; const max41bit = 1099511627775; static $machineId = null; public static function machineId($mId = 0) { self::$machineId = $mId; } public static function generateParticle() { /* * Time - 42 bits */ $time = floor(microtime(true) * 1000); /* * Substract custom epoch from current time */ $time -= self::EPOCH; /* * Create a base and add time to it */ $base = decbin(self::max41bit + $time); /* * Configured machine id - 10 bits - up to 1024 machines */ if(!self::$machineId) { $machineid = self::$machineId; } else { $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT); } /* * sequence number - 12 bits - up to 4096 random numbers per machine */ $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT); /* * Pack */ $base = $base.$machineid.$random; /* * Return unique time id no */ return bindec($base); } public static function timeFromParticle($particle) { /* * Return time */ return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH; }}
调用方法如下
Particle::generateParticle($machineId);//生成IDParticle::timeFromParticle($particle);//反向计算时间戳
以上for 5000+重复率为5%,效率比较高。
以下for100000次重复率0,效率低。
class IdWork{ //开始时间,固定一个小于当前时间的毫秒数即可 const twepoch = 1474992000000;//2016/9/28 0:0:0 //机器标识占的位数 const workerIdBits = 5; //数据中心标识占的位数 const datacenterIdBits = 5; //毫秒内自增数点的位数 const sequenceBits = 12; protected $workId = 0; protected $datacenterId = 0; static $lastTimestamp = -1; static $sequence = 0; function __construct($workId=0, $datacenterId=0){ //机器ID范围判断 $maxWorkerId = -1 ^ (-1 << self::workerIdBits); if($workId > $maxWorkerId || $workId< 0){ throw new Exception("workerId can't be greater than ".$this->maxWorkerId." or less than 0"); } //数据中心ID范围判断 $maxDatacenterId = -1 ^ (-1 << self::datacenterIdBits); if ($datacenterId > $maxDatacenterId || $datacenterId < 0) { throw new Exception("datacenter Id can't be greater than ".$maxDatacenterId." or less than 0"); } //赋值 $this->workId = $workId; $this->datacenterId = $datacenterId; } //生成一个ID public function nextId(){ $timestamp = $this->timeGen(); $lastTimestamp = self::$lastTimestamp; //判断时钟是否正常 if ($timestamp < $lastTimestamp) { throw new Exception("Clock moved backwards. Refusing to generate id for %d milliseconds", ($lastTimestamp - $timestamp)); } //生成唯一序列 if ($lastTimestamp == $timestamp) { $sequenceMask = -1 ^ (-1 << self::sequenceBits); self::$sequence = (self::$sequence + 1) & $sequenceMask; if (self::$sequence == 0) { $timestamp = $this->tilNextMillis($lastTimestamp); } } else { self::$sequence = 0; } self::$lastTimestamp = $timestamp; // //时间毫秒/数据中心ID/机器ID,要左移的位数 $timestampLeftShift = self::sequenceBits + self::workerIdBits + self::datacenterIdBits; $datacenterIdShift = self::sequenceBits + self::workerIdBits; $workerIdShift = self::sequenceBits; //组合4段数据返回: 时间戳.数据标识.工作机器.序列 $nextId = (($timestamp - self::twepoch) << $timestampLeftShift) | ($this->datacenterId << $datacenterIdShift) | ($this->workId << $workerIdShift) | self::$sequence; return $nextId; } //取当前时间毫秒 protected function timeGen(){ $timestramp = (float)sprintf("%.0f", microtime(true) * 1000); return $timestramp; } //取下一毫秒 protected function tilNextMillis($lastTimestamp) { $timestamp = $this->timeGen(); while ($timestamp <= $lastTimestamp) { $timestamp = $this->timeGen(); } return $timestamp; }}
0 0
- PHP使用SnowFlake算法生成唯一ID
- 【Zanuck 镇】编写php高性能snowflake算法插件(分布式64位唯一性自增id生成算法)
- Twitter的分布式自增ID算法Snowflake的PHP实现,Snowflake PHP版本,高并发唯一id,全局唯一id,不重复id
- C语言实现分布式自增有序的唯一ID生成算法-snowflake算法
- C语言实现分布式自增有序的唯一ID生成算法-snowflake算法
- 基于业务对Twitter生成全局唯一ID的SnowFlake算法的改造
- php 生成唯一ID
- php生成唯一id
- PHP生成唯一ID
- [算法] 生成唯一id
- twitter id生成算法snowflake详解
- 基于Twitter的snowflake算法生成ID
- PHP生成唯一标识ID
- php 生成分布式唯一ID
- PHP----生成唯一的ID
- php订单生成唯一Id
- 使用uniqid生成唯一id
- php 生成唯一id /唯一标识符/唯一订单号
- 虚函数、虚指针和虚表
- CCF 201509-2
- 单页WEB应用(九),终篇-总结和发布
- hibernate @Where注解
- IOS 异常错误积累 swift
- PHP使用SnowFlake算法生成唯一ID
- 数据结构系列之链表——单链表插入值为num的节点
- 理解Spark的核心RDD
- 面试题:“你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”
- 开发网页,不知道js出错在哪怎么办??
- Java三路快速排序
- 面试问题整理
- uboot下init_sequence_f函数之init_post
- Could not load codec 'Lucene54'. Did you forget to add lucene-backward-codecs.jar?