存档

文章标签 ‘订单’

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创建不重复的随机字符串,可以用来用作图片保存(文件名)或者创建订单号。

css.php