PHP生成唯一ID之SnowFlake算法


Posted in PHP onDecember 17, 2016

前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的。文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过直接用自增主键,但是感觉这样有点暴露文章数量,有同学说可以把初始值设高一点,可是还是可以通过ID差算出一段时间内的文章数量,所以需要一种可以生成唯一ID的算法。

考虑过的方法有

  1. 直接用时间戳,或者以此衍生的一系列方法
  2. Mysql自带的uuid

以上两种方法都可以查到就不多做解释了

最终选择了Twitter的SnowFlake算法

这个算法的好处很简单可以在每秒产生约400W个不同的16位数字ID(10进制)

原理很简单

ID由64bit组成

其中 第一个bit空缺

41bit用于存放毫秒级时间戳

10bit用于存放机器id

12bit用于存放自增ID

除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。
下面是PHP源码

<?php
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);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳

这里我做了改良 如果机器ID传0 就会去掉这10bit 因为有些时候我们可能用不到这么多ID

PHP 相关文章推荐
自己动手做一个SQL解释器
Oct 09 PHP
一个SQL管理员的web接口
Oct 09 PHP
PHP用户指南-cookies部分
Oct 09 PHP
PHP读MYSQL中文乱码的解决方法
Dec 17 PHP
php实现执行某一操作时弹出确认、取消对话框
Dec 30 PHP
thinkphp的c方法使用示例
Feb 24 PHP
php判断访问IP的方法
Jun 19 PHP
php获取远程文件内容的函数
Nov 02 PHP
深入浅析php中sprintf与printf函数的用法及区别
Jan 08 PHP
php生成毫秒时间戳的实例讲解
Sep 22 PHP
PHP实现重载的常用方法实例详解
Oct 18 PHP
Yii框架操作cookie与session的方法实例详解
Sep 04 PHP
简单解决微信文章图片防盗链问题
Dec 17 #PHP
PHP 7.1新特性的汇总介绍
Dec 16 #PHP
浅谈PHP命令执行php文件需要注意的问题
Dec 16 #PHP
PHP+Ajax 检测网络是否正常实例详解
Dec 16 #PHP
php微信公众号开发(4)php实现自定义关键字回复
Dec 15 #PHP
php微信公众号开发(3)php实现简单微信文本通讯
Dec 15 #PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
Dec 15 #PHP
You might like
PHP 和 MySQL 基础教程(一)
2006/10/09 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
PHP用户注册邮件激活账户的实现代码
2017/05/31 PHP
一个高效的JavaScript压缩工具下载集合
2007/03/06 Javascript
自己动手实现jQuery Callbacks完整功能代码详解
2013/11/25 Javascript
给ListBox添加双击事件示例代码
2013/12/02 Javascript
js中的preventDefault与stopPropagation详解
2014/01/29 Javascript
jquery提交form表单简单示例分享
2014/03/03 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
2014/05/16 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
Node.js制作简单聊天室
2017/01/12 Javascript
Vue自定义指令拖拽功能示例
2017/02/17 Javascript
使用canvas及js简单生成验证码方法
2017/04/02 Javascript
bootstrap响应式工具使用详解
2017/11/29 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
2018/11/14 Javascript
微信小程序云开发实现云数据库读写权限
2019/05/17 Javascript
vue 组件简介
2020/07/31 Javascript
原生jQuery实现只显示年份下拉框
2020/12/24 jQuery
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
matlab中实现矩阵删除一行或一列的方法
2018/04/04 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
2019/06/21 Python
pandas数据拼接的实现示例
2020/04/16 Python
Django数据模型中on_delete使用详解
2020/11/30 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
英国设计师泳装、沙滩装和比基尼在线精品店:Beach Cafe
2019/08/28 全球购物
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/04/11 面试题
高中竞选班长演讲稿
2014/04/24 职场文书
品德评语大全
2014/05/05 职场文书
2014年党员整改措施范文
2014/09/21 职场文书
2014公司年终工作总结
2014/12/19 职场文书
应聘教师求职信范文
2015/03/20 职场文书
2015年学习部工作总结范文
2015/03/31 职场文书
2016年119消防宣传日活动总结
2016/04/05 职场文书