php生成100%不重复随机字符串实现方法
在日常php web开发中经常会用到随机字符串, 我们用随机字符串的目的很大程度上是为了不重复, 本文就结合我的实际经验来分析下, 如何实现100%不重复随机字符串.
{ 随机字符串分类 }
a. 一定概率不重复的随机字符串
b. 100%不会重复的随机字符串
{ a. 一定概率不重复的随机字符串 }
举一个经典的实现方法:
$seed = [];
$seed['time'] = time();
$seed['ip'] = Yii::app()->request->userHostAddress; //get ip address in Yii
$seed['randNum'] = mt_rand(10000, 99999);
$randString = implode('_', $seed);
echo $randString;//1463624229_127.0.0.1_41111
上面的算法实现原理是利用unixtimestamp+ip address把前置条件限定在一秒内, 针对单个ip地址. 然后通过10000-99999的90000个随机数来控制随机概率
一秒 + 单个ip + 1/90000的概率, 针对用户量不太大的小型系统已经足够用了, 值得说明的是上述实现方法和UUID之类没有本质差别, 只是为了方便阅读
但是, 如果放眼RESTful架构中, 一个100台server的集群里, 那么问题就不一样了.
如果用户A ip一秒可以发起10k次请求, 我们基本就可以认为上述方法已经无法有效的生成非重复字符串了
{ b. 100%不重复的随机字符串 }
其实b比a简单, 有时候只是我们认为的把一些事情想复杂了.
稍微放低一点要求来想: 1, 2, 3, 4 不就是4个不重复的字符串吗?
什么要有一定的长度和不那么容易看出来?
那就通过md5(1), 来实现就可以了
具体实现php代码如下:
$topic = new Topic();
//TODO add necessary attributes
if ($topic->save()) {
$randString = md5($topic->t_id);
echo $randString;//c20ad4d76fe97759aa27a0c99bff6710
}else{
//save fail, do sth
}
说明, 中间用的是MySQL之类的数据库, 通过自增PK来实现+1, 然后变化到一定长度这里用的是md5, 其他方法亦可
在对精度要求高并比较复杂的情况下, 牺牲一次简单数据库操作或者类似方式来获取100%不重复的字符串, 在性能和可靠性的权衡上是可取的
当然这只是一个思路希望能够抛砖引玉. 欢迎有想法的留言.
留言