PHP 的 uniqid 函数产生的 id 真的是唯一的么?

最近使用到了 uniqid,就产生了疑问?uniqid 生成的 id 由什么组成?真的是唯一的么?什么情况下会产生冲突?

从文档中看到 uniqid 函数有两个参数

uniqid 的结构

看源码:

PHP_FUNCTION(uniqid)
{
...
gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
sec = (int) tv.tv_sec;
usec = (int) (tv.tv_usec % 0x100000); ...
if (more_entropy) {
uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
} else {
uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
} RETURN_STR(uniqid);
}

基本就了解清楚了。uniqid 是由四个部分组成:

prefix + sec + usec + “.” + php_combined_lcg

其中 prefix 就是 uniqid 函数的第一个参数。它是一个字符串,传递进来什么,就直接返回什么。

sec 是当前时钟的秒,usec 是毫秒,这两个值都是从 gettimeofday 获取的。换句话说,只要在一台机器上,两个 php 程序在同一个毫秒内获取的 sec 和 usec 是一样的。

php_combined_lcg 是 uniqid 的第二个参数决定的,它是一个墒值,它是使用线性同余生成一个 0 ~ 1 之间的随机数。如果第二个参数为 true,就有这个值,如果第二个参数为 false,就没有这个值。

比如:

➜  ~ php -r 'echo uniqid("my_", true);'
my_5afe9b414c2141.76621929

结论

所以说,如果我们单纯使用 uniqid() 这个方法,不带任何参数的话,这个方法只能保证单个进程,在同一个毫秒内是唯一的。如果使用uniqid("", true)。 带了一个墒值,自身已经有一个随机的方式能保证生成的id的随机性了。但是由于线性同余是比较简单的生成随机数的算法,随机性有可能还不够,所以,网上流传的一种更随机数值的方式是:

uniqid(mt_rand(), true)

其中 mt_rand() 生成随机数就不是使用线性同余生成随机数的方式了,而是使用 Mersenne Twister Random Number Generator (梅森旋转算法)。换句话说,上面这个 id 由两种随机算法 + 时间戳生成。基本上,这个算法在很大程度上能保证唯一性了(如果要问冲突率的话,估计只有数学系学生能研究出来了...)。

上面的这个给出的id会有一个点号,而且长度并不是128bit。如果希望生成uuid,就需要一个hash,不管是md5,sha1 都是可以选择的。所以网上又有一种生成唯一码的方式。

md5(uniqid(mt_rand(), true))

但是,本质上,这两种方式的随机性是相等的。

PHP 的 uniqid 函数产生的 id 真的是唯一的么?的更多相关文章

  1. uniqid() 函数 和 microtime()函数

    uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID.语法 uniqid(prefix,more_entropy) 参数     描述prefix     可选.为 ID 规定前缀.如果 ...

  2. PHP uniqid() 函数

    实例 生成一个唯一的 ID: <?phpecho uniqid();?>高佣联盟 www.cgewang.com 定义和用法 uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ...

  3. 如何实现用户id生成一个唯一邀请码

    #如何实现用户id生成一个唯一邀请码 #创建验证码 function createCode($user_id) { static $source_string = 'E5FCDG3HQA4B1NOPI ...

  4. uniqid函数产生唯一id,减少碰撞几率

    $uuid = str_replace(".","",uniqid(mt_rand(100000,999999),true)); //基于当前时间微妙数,与mt ...

  5. Sqlserver 中系统表sysobjects、syscolumns以及函数object_id

    1.sysobjects 系统对象表. 保存当前数据库的对象,如约束.默认值.日志.规则.存储过程等 sysobjects 重要字段解释: sysObjects ( Name sysname, --o ...

  6. 分割函数和根据Id串返回名字

    需求:函数传入一个字符串参数 例如  123-456 将这个字符串123-456拆成两个值 123   456,在通过两个值分别查出数据(例如 张三  李四),拼接成     张三-李四 --声明变量 ...

  7. 2、fork函数与进程ID

    1. fork函数 fork函数用于克隆一份当前的进程资源,调用fork函数之后,进程一分为二,并且两个进程的资源是一样的(只是资源内容完全一样,并不是同一份资源).fork函数的函数原型为:pid_ ...

  8. 那个你经常用的abs函数(取绝对值)真的总是返回非负数吗?

    前几天在牛客网看到一道关于abs()函数返回值的题目,见下图,当时还没反应过来,第一反应是:自从我开始学C语言,就知道它是用来求int数的绝对值的,返回值当然是0或者正数啊,一看答案就是A. 后来思来 ...

  9. 根据用户id生成一个唯一邀请码

    需求描述:根据用户id生成与之对应的唯一邀请码,范围为‘0-9A-Z’. 这个需求的重点在于加粗的部分,也就是要能够根据邀请码反推出用户ID,这样邀请码就不用入库了,在用户量很大的情况下,性能可以得到 ...

随机推荐

  1. Unix/Linux中的read和write函数

    文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符.当读或写一个文件时,使用open或creat ...

  2. 【面试笔试算法】Problem 1 : DP滑雪问题--网易互联网算法实习生2017笔试题

    Description Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激.可是 为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  3. 物理引擎中velocity的单位是个什么鬼?

    现在, 你可能对于什么是velocity的单位感到奇怪.他是单位秒中经过点的一个可测量的量(pt/s).如果你想要在iphone横屏从左往右的移动物体,并且你想在1秒内移动1024个点,那么物体的x速 ...

  4. Struts2技术内幕 读书笔记一 框架的本质

    本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...

  5. LeetCode之“散列表”:Contains Duplicate && Contains Duplicate II

     1. Contains Duplicate 题目链接 题目要求: Given an array of integers, find if the array contains any duplica ...

  6. javascript数组特性

    数组是一段线性分配的内存, 它通过整数计算偏移并访问其中的元素. 数组是一种性能出色的数据结构. 1.数组字面量 数组字面量提供了一种非常方便地创建新数组的表示法. 多个用逗号分隔的值的表达式. 数组 ...

  7. Oracle 10g DG 数据文件迁移

    背景:某客户Oracle 10g 的DG由于空间不足,之前将部分数据文件迁移到其他目录,如今原目录扩容成功,要将之前迁移的数据文件再次迁移回来. 环境:Oracle 10.2.0.5 DG 单机 首先 ...

  8. DB2许可证文件

    与 DB2® 数据库产品相关联的许可证文件有两种类型: 基本许可证密钥和 完整许可证密钥.这些许可证密钥以纯文本格式存储,通常称为 许可证文件或 许可证权利证书. "基本"许可证未 ...

  9. Web 前台优化

    大型网站--前端性能优化和规范 2013-10-28 09:00 by 贤达, 2769 阅读, 10 评论, 收藏, 编辑   Web性能涉及的范围太广,但一般web开发者在程序上线以后很多都曾遇到 ...

  10. python自动重试第三方包retrying

    最近写了一个爬虫,需要连接国外的一个网站,经常出现掉线的情况,自己写了一个自动重连的代码,但感觉不够简洁... 后来就上万能的github,找到了一个第三包,基本能满足我的要求.这个第三方包就是ret ...