php简洁版雪花算法Snowflake

原理介绍:

Snowflake的核心思想是将64bit的二进制数字分成若干部分,每一部分都存储有特定含义的数据,比如说时间戳、机房ID、机器ID、序列号等等,最终生成全局唯一的有序ID。它的标准算法是这样的:

0       0000000000000000000000000000000000000000  0000000000   000000000000
符号位  41位时间戳,大约够69年                    10位(机房+机器ID)  12位序列号   

具体位数怎么分配,其实可以根据自己的情况来,比如如果只有两个机器,那么用10位显然是浪费的,根据自己情况分配即可

相关知识:

二进制转十进制:

比如 11010[2进制] = 1X2^4+1X2^3+0X2^2+1X2^1+0X2^0
=26[10进制],二进制数转换成十进制数的方法是按权展开就是这样做的
注:2^4表示2的4次方,任何非0数字的0次方都等于1

十进制转二进制:

789=1100010101
789/2=394 余1 第10位
394/2=197 余0 第9位
197/2=98 余1 第8位
98/2=49 余0 第7位
49/2=24 余1 第6位
24/2=12 余0 第5位
12/2=6 余0 第4位
6/2=3 余0 第3位
3/2=1 余1 第2位
1/2=0 余1 第1位

最后把余数从下往上连起来即为: 1100010101

PHP实现

<?php
/**
 *  分布式 id 生成类     组成: <毫秒级时间戳+机房id+机器id+序列号>
 *  默认情况下41bit的时间戳可以支持该算法使用69年,5bit的机房id可以支持31台机器,5bit的工作机器id可以支持31台机器,序列号支持1毫秒产生4095个自增序列id
 */
class IdCreate
{
    const EPOCH = 1640856551866;    //开始时间,固定一个小于当前时间的毫秒数,这样后续的时间戳毫秒基于此开始时间才能达到69年;
    const max12bit = 4095;

    static $dataCenterId = null;      // 机房id
    static $machineId = null;      // 机器id

    public static function createOnlyId($dataCenterId = 0,$machineId = 0)
    {
        self::$machineId = $machineId;
        self::$dataCenterId = $dataCenterId;
        // 时间戳 41字节
        $time = floor(microtime(true) * 1000);
        // 当前时间 与 开始时间 差值,这样就可以有69年的时间
        $time -= self::EPOCH;
        // 二进制的 毫秒级时间戳
        $timeStr = str_pad(decbin($time), 41, "0", STR_PAD_LEFT);
        // 机房id  5 字节
        $dataCenterId = str_pad(decbin(self::$dataCenterId), 5, "0", STR_PAD_LEFT);
        // 机器id  5 字节
        $machineId = str_pad(decbin(self::$machineId), 5, "0", STR_PAD_LEFT);

        // 序列数 12字节
        $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);
        //正常应该搞自增id,这里为了演示,所以用了随机数,使用redis的自增id比较好:
        //REDIS::incr($time.self::$dataCenterId.self::$machineId);
        // 拼接
        $base = $timeStr.$dataCenterId.$machineId.$random;
        // 转化为 十进制 返回
        return bindec($base);
    }
}
    $dataCenterId = 2;
    $machineId = 1;
    $cast_id = IdCreate::createOnlyId($dataCenterId,$machineId);
    echo $cast_id;

生成唯一值

13648311620966
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值