一行代码实现简单的唯一定长ID的生成。

:blush:

md5(uniqid(php_uname('n').getmypid().session_create_id(), true).mt_rand(100000,999999));

//这么长的结果:70627629d983455ad7a4c6869a632994

大佬来分析分析,这个能实现唯一了吗?反正我用2年了,没出现重复的!呵呵

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 35
/*
* 薄雾算法
*
* 1      2                                                     48         56       64
* +------+-----------------------------------------------------+----------+----------+
* retain | increas                                             | salt     | sequence |
* +------+-----------------------------------------------------+----------+----------+
* 0      | 0000000000 0000000000 0000000000 0000000000 0000000 | 00000000 | 00000000 |
* +------+-----------------------------------------------------+------------+--------+
*
* 0. 最高位,占 1 位,保持为 0,使得值永远为正数;
* 1. 自增数,占 47 位,自增数在高位能保证结果值呈递增态势,遂低位可以为所欲为;
* 2. 随机因子一,占 8 位,上限数值 255,使结果值不可预测;
* 3. 随机因子二,占 8 位,上限数值 255,使结果值不可预测;
*
* 编号上限为百万亿级,上限值计算为 140737488355327 即 int64(1 << 47 - 1),假设每天取值 10 亿,能使用 385+ 年
 */

class Mist
{
    public const saltBit = 8;          // 随机因子二进制位数

    public const saltShift = 8;        // 随机因子移位数

    public const increasShift = self::saltBit + self::saltShift; // 自增数移位数

    public $increas = 0;                // 自增数

    public $saltA = 0;                  // 随机因子一

    public $saltB = 0;                  // 随机因子二

    public function __construct($increas = 1)
    {
        $this->increas = $increas;
    }

    public function generate(): int
    {
        $this->increas = ++$this->increas;
        // 获取随机因子数值
        try {
            $this->saltA = random_int($this->saltA, 255);
        } catch (\Exception $e) {
            $this->saltA = $this->saltA++;
        }
        try {
            $this->saltB = random_int($this->saltB, 255);
        } catch (\Exception $e) {
            $this->saltB = $this->saltB++;
        }
        return (int) ($this->increas << self::increasShift) | ($this->saltA << self::saltShift) | $this->saltB;
    }
}

$uuid = (new Mist(1))->generate();
#> > 153290
1年前 评论
liziyu (楼主) 1年前
kphcdr 1年前
cexll (作者) 1年前
kphcdr 1年前
cevin 1年前
raybon 1年前
liziyu (楼主) 1年前
bibi小将 5个月前

不如 换成这个: ramsey/uuid

use  Illuminate\Support\Str;  return  (string)  Str::uuid();
// laravel 自带, 替换中间的减号就行了
1年前 评论
liziyu (楼主) 1年前

:+1: :+1: :+1: :+1: :+1: :+1:

1年前 评论

这种 并发生成的话 很吃性能 甚至内存溢出

1年前 评论
liziyu (楼主) 1年前

怎么说呢,全靠uniqid和session_create_id撑着,和算法没啥关系

1年前 评论
Imuyu (作者) 1年前
liziyu (楼主) 1年前
/*
* 薄雾算法
*
* 1      2                                                     48         56       64
* +------+-----------------------------------------------------+----------+----------+
* retain | increas                                             | salt     | sequence |
* +------+-----------------------------------------------------+----------+----------+
* 0      | 0000000000 0000000000 0000000000 0000000000 0000000 | 00000000 | 00000000 |
* +------+-----------------------------------------------------+------------+--------+
*
* 0. 最高位,占 1 位,保持为 0,使得值永远为正数;
* 1. 自增数,占 47 位,自增数在高位能保证结果值呈递增态势,遂低位可以为所欲为;
* 2. 随机因子一,占 8 位,上限数值 255,使结果值不可预测;
* 3. 随机因子二,占 8 位,上限数值 255,使结果值不可预测;
*
* 编号上限为百万亿级,上限值计算为 140737488355327 即 int64(1 << 47 - 1),假设每天取值 10 亿,能使用 385+ 年
 */

class Mist
{
    public const saltBit = 8;          // 随机因子二进制位数

    public const saltShift = 8;        // 随机因子移位数

    public const increasShift = self::saltBit + self::saltShift; // 自增数移位数

    public $increas = 0;                // 自增数

    public $saltA = 0;                  // 随机因子一

    public $saltB = 0;                  // 随机因子二

    public function __construct($increas = 1)
    {
        $this->increas = $increas;
    }

    public function generate(): int
    {
        $this->increas = ++$this->increas;
        // 获取随机因子数值
        try {
            $this->saltA = random_int($this->saltA, 255);
        } catch (\Exception $e) {
            $this->saltA = $this->saltA++;
        }
        try {
            $this->saltB = random_int($this->saltB, 255);
        } catch (\Exception $e) {
            $this->saltB = $this->saltB++;
        }
        return (int) ($this->increas << self::increasShift) | ($this->saltA << self::saltShift) | $this->saltB;
    }
}

$uuid = (new Mist(1))->generate();
#> > 153290
1年前 评论
liziyu (楼主) 1年前
kphcdr 1年前
cexll (作者) 1年前
kphcdr 1年前
cevin 1年前
raybon 1年前
liziyu (楼主) 1年前
bibi小将 5个月前

snowflake

1年前 评论

session_create_id 有这个,其他的都可以删掉了。

1年前 评论
DonnyLiu

用雪花算法 :smile:

1年前 评论
陈先生

If session is not active, collision check is omitted.

1年前 评论
liziyu (楼主) 1年前
陈先生 (作者) 1年前
陈先生 (作者) 1年前
liziyu (楼主) 1年前

还是要看并发,qps1的话 time() 函数就可以解决 :joy:

1年前 评论

唯一性暂且不讨论,再次生成还能得到同样的结果吗?

1年前 评论
陈先生 1年前
liziyu (楼主) 1年前
陈先生 1年前

uniqid 能用这个函数基本上重复问题几乎都解决掉了,更不用说再加点其他参数了 :joy:

1年前 评论

抛开各种所谓的算法,只要长度足够长,重复的几率很低

1年前 评论
laradocs

世界上没有两片完全相同的树叶。

— 莱布尼茨

github.com/Meituan-Dianping/Leaf

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!