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

:blush:

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

//这么长的结果:70627629d983455ad7a4c6869a632994

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

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 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
3年前 评论
Image liziyu (楼主) 3年前
Image kphcdr 3年前
Image cexll (作者) 3年前
Image kphcdr 3年前
Image cevin 3年前
Image raybon 3年前
Image liziyu (楼主) 3年前
Image bibi小将 2年前

不如 换成这个: ramsey/uuid

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

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

3年前 评论

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

3年前 评论
Image liziyu (楼主) 3年前

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

3年前 评论
Image Imuyu (作者) 3年前
Image liziyu (楼主) 3年前
/*
* 薄雾算法
*
* 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
3年前 评论
Image liziyu (楼主) 3年前
Image kphcdr 3年前
Image cexll (作者) 3年前
Image kphcdr 3年前
Image cevin 3年前
Image raybon 3年前
Image liziyu (楼主) 3年前
Image bibi小将 2年前

snowflake

3年前 评论

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

3年前 评论
DonnyLiu

用雪花算法 :smile:

3年前 评论

If session is not active, collision check is omitted.

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

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

3年前 评论

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

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

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

3年前 评论

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

3年前 评论
laradocs

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

— 莱布尼茨

github.com/Meituan-Dianping/Leaf

3年前 评论

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