php生成不重复的随机字符串
2020年8月6日
没有评论
最近需要实现一个创建不重复订单号的功能,所以书写了一下简单的php代码,基本上可以实现php创建不重复的随机字符串(未考虑多台服务器分布执行,本代码只考虑单台服务器执行),不能保证100%不重复,但是经过实践,1亿条都为出现重复(也没有考虑高并发的情况下),仅供大家参考。
贴出代码:
class createOurOrderNum{
var $dict='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*!';
var $short64='^';//转为64进制后不足指定长度的补足字符串
/*
1,本class只适合在64位系统+64位php软件环境下进行,否则decb64和b64dec会无法正确互相转换
2,满足1的条件下,本class只适合转换小于9223372036854775807的数字
3,不要满足1的条件下,本class只适合转换小于2147483647的数字
4,本class中的createNum()函数中decb64转换的是12位长度数字(即最大999999999)
*/
/*
//将64进制转换为10进制
function b64dec($b64){
$dec=0;
$len=strlen($b64);
for($i=0;$i<$len;$i++){
$b=strpos($this->dict,$b64[$i]);
$j=$len-$i-1;
$dec+=($j==0?$b:(2<<(6*$j-1))*$b);
}
return $dec;
}
//如何根据已经生成的订单号来解密获得时间戳和微秒
function getNumberMicrotime($num){
//将订单号前8位日期获取到
$ymd=substr($num,0,8);
//截取订单号最后8位,再将8位中的补足字符串全部替换为空,获得64进制
$str64=str_replace($this->short64,'',substr($num,strlen($num)-8));
//将64进制转为10进制
$str10=$this->b64dec($str64);
//将$ymd转为时间戳,然后截取前4位,再截取$str10前6位,则为订单号创建的时间戳
$times[0]=substr(strtotime($ymd),0,4).substr($str10,0,6);
//截取$str10后6位则为微秒数
$time[1]=substr($str10,6);
return $times[0].'.'.$time[1];
}
*/
//将10进制转换为64进制
function decb64($dec){
$b64='';
do{
$b64=$this->dict[($dec%64)].$b64;
$dec/=64;
}
while($dec>=1);
return $b64;
}
function createNum(){
$time=explode(' ',microtime());
//利用时间戳+毫秒数+随机数,hash加密之后,来通过uniqid创建基本不重复的种子
$seed=uniqid(hash('sha1',$time[1].$time[0].mt_rand()),true);
//再将种子+随机数+随机英文或数组,加密之后,取16位md5值
$name=substr(md5($seed.mt_rand().substr('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',(mt_rand(0,61)),1)),8,16);
//同一天最大毫秒数为86400,所以时间戳最后6位(86400是5位)不会重复,所以我们可以去除前4位
//然后加上毫秒来转换为64进制(6+6位返回的是7位长度64进制)
//最大值应该是decb64('999999999999')='EZKfG==';
$name64=$this->decb64(substr($time[1],4).sprintf('%06u',substr($time[0],2,6)));
//12位数字转为64进制之后有可能是8位长度(不排除),所以$name转为64进制之后的不足8位长度要补足(保持长度一致)
$nameLen=strlen($name64);
if($nameLen<8){
$buzu='';
for($i=0;$i<(8-$nameLen);$i++){$buzu.=$this->short64;}
$name64=$buzu.$name64;
}
else {
//如果大于8则截取,基本情况不会出现
$name64=substr($name64,0,8);
}
//要以$time[1]为时间戳转换Ymd
return date('Ymd',$time[1]).$name.$name64;
}
}
php调用方法:
$createOurOrderNum=new createOurOrderNum();
$no=$createOurOrderNum->createNum();
echo 'order numer:'.$no;
echo '<br />';
echo 'order number timestamp:'.$createOurOrderNum->getNumberMicrotime($no);
以上就是利用php创建不重复的随机字符串,可以用来用作图片保存(文件名)或者创建订单号。
近期评论