PHP 的 uniqid 函数产生的 id 真的是唯一的么?
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 真的是唯一的么?的更多相关文章
- uniqid() 函数 和 microtime()函数
uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID.语法 uniqid(prefix,more_entropy) 参数 描述prefix 可选.为 ID 规定前缀.如果 ...
- PHP uniqid() 函数
实例 生成一个唯一的 ID: <?phpecho uniqid();?>高佣联盟 www.cgewang.com 定义和用法 uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ...
- 如何实现用户id生成一个唯一邀请码
#如何实现用户id生成一个唯一邀请码 #创建验证码 function createCode($user_id) { static $source_string = 'E5FCDG3HQA4B1NOPI ...
- uniqid函数产生唯一id,减少碰撞几率
$uuid = str_replace(".","",uniqid(mt_rand(100000,999999),true)); //基于当前时间微妙数,与mt ...
- Sqlserver 中系统表sysobjects、syscolumns以及函数object_id
1.sysobjects 系统对象表. 保存当前数据库的对象,如约束.默认值.日志.规则.存储过程等 sysobjects 重要字段解释: sysObjects ( Name sysname, --o ...
- 分割函数和根据Id串返回名字
需求:函数传入一个字符串参数 例如 123-456 将这个字符串123-456拆成两个值 123 456,在通过两个值分别查出数据(例如 张三 李四),拼接成 张三-李四 --声明变量 ...
- 2、fork函数与进程ID
1. fork函数 fork函数用于克隆一份当前的进程资源,调用fork函数之后,进程一分为二,并且两个进程的资源是一样的(只是资源内容完全一样,并不是同一份资源).fork函数的函数原型为:pid_ ...
- 那个你经常用的abs函数(取绝对值)真的总是返回非负数吗?
前几天在牛客网看到一道关于abs()函数返回值的题目,见下图,当时还没反应过来,第一反应是:自从我开始学C语言,就知道它是用来求int数的绝对值的,返回值当然是0或者正数啊,一看答案就是A. 后来思来 ...
- 根据用户id生成一个唯一邀请码
需求描述:根据用户id生成与之对应的唯一邀请码,范围为‘0-9A-Z’. 这个需求的重点在于加粗的部分,也就是要能够根据邀请码反推出用户ID,这样邀请码就不用入库了,在用户量很大的情况下,性能可以得到 ...
随机推荐
- C++11特性 - Smart Pointers 智能指针
已经有成千上万的文章讨论这个问题了,所以我只想说:现在能使用的,带引用计数,并且能自动释放内存的智能指针包括以下几种: unique_ptr: 如果内存资源的所有权不需要共享,就应当使 ...
- WinCE系统声音定制
作者:ARM-WinCE 2010的第一篇Blog,介绍一下WinCE系统声音的定制.说白了,就是设置注册表.WinCE系统启动的开机音乐,点击触摸屏以及键盘输入的按键音,还有系统运行过程中的各种声音 ...
- Socket层实现系列 — accept()的实现(二)
本文主要分析accept()的阻塞等待和唤醒. 内核版本:3.6 Author:zhangskd @ csdn blog 等待队列 (1)socket的等待队列 /* * @sk_wq: sock w ...
- CAS实现单点登录--错误记录
遇到的错误: 生成证书: 1. 命令:keytool -genkey -alias smalllove -keyalg RSA -keystore C:/keys/smallkey 错误:ja ...
- C语言之linux内核实现最大公约数算法
最大公约数算法,又称欧几里德算法,至今已有几千年的历史了.在我们开始学习C语言的时候最常用的算法就是辗转相除法,其实在linux内核中,内核也是使用这样的方法实现两数最大公约数的计算. 两个整数的最大 ...
- Smali语法汇总(二)
Opcode 操作码(hex) Opcode name 操作码名称 Explanation 说明 Example 示例 0F return vx 返回在vx寄存器的值. 0F00 - return v ...
- 基于MT6752/32平台 Android L版本驱动移植步骤
基于MT6752/32平台 Android L版本驱动移植步骤 根据MK官网所述,在Android L 版本上Turnkey ABS 架构将会phase out,而Mediatek Turnkey架构 ...
- ROS探索总结(十二)——坐标系统
在机器人的控制中,坐标系统是非常重要的,在ROS使用tf软件库进行坐标转换. 相关链接:http://www.ros.org/wiki/tf/Tutorials#Learning_tf 一.tf简介 ...
- LeetCode(33)-Pascal's Triangle II
题目: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return ...
- 抛开rails使用ActiveRecord连接数据库
今天是大年三十,明天就正式进入羊年鸟,给所有程序猿(媛)同人拜个年吧!祝大家身体健康,事业有成,财源广进哦! 话归正题,以前都是在rails中使用数据库,或者在rails的console中使用:我们如 ...