存档

文章标签 ‘不重复’

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

php新建随机图片或者文件保存文件名,可以防止不重复。

2017年9月26日 没有评论

php新建随机图片或者文件保存文件名,可以防止不重复。请使用以下函数。如果需要可以稍作修改。

function randPicName(){
$time=explode(‘ ‘,microtime());
return $time[1].sprintf(‘%06u’,substr($time[0],2,6)).mt_rand(100000,999999).substr(‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’,(mt_rand(0,61)),1).substr(‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’,(mt_rand(0,61)),1);
}

分类: php学习 标签: , ,

php实现生产不重复的6位数字+2位字母

2016年4月21日 没有评论

最近要实现一个功能,用php生产一个8位不重复的编号(前2位是字母,后6位是数字),用了2套方案:

第一套是实现按数字增长,比如:

AA000000->AA000001->…->AA999999->AB000000->AB000001->…->YY999999

第二套是实现按字母增长后增长数字,比如:

AA000000->AB000000->…->AY000000->AA000001->AB000001->…->YY999999

方法1:

function getNewBindCode($oldCode){
		if(empty($oldCode)){return 'AA000000';}
		$old_en_1=substr($oldCode,0,1);
		$old_en_2=substr($oldCode,1,1);
		$old_shuzi=intval(substr($oldCode,2));
		if($old_shuzi==999999){
			$enToShuzi=array('A'=>1,'B'=>2,'C'=>3,'D'=>4,'E'=>5,'F'=>6,'G'=>7,'H'=>8,'J'=>9,'K'=>10,'L'=>11,'M'=>12,'N'=>13,'P'=>14,'Q'=>15,'R'=>16,'S'=>17,'T'=>18,'U'=>19,'V'=>20,'W'=>21,'X'=>22,'Y'=>23);
			$old_en_1=$enToShuzi[$old_en_1];
			$old_en_2=$enToShuzi[$old_en_2];
			if($old_en_2==23){
				$new_en_1=$old_en_1+1;
				$new_en_2=1;
			}
			else {
				$new_en_1=$old_en_1;
				$new_en_2=$old_en_2+1;
			}
			$new_en=array_search($new_en_1,$enToShuzi).array_search($new_en_2,$enToShuzi);
			$new_shuzi='000000';
		}
		else {
			$new_en=$old_en_1.$old_en_2;
			$new_shuzi=$old_shuzi+1;
		}
		switch(strlen($new_shuzi)){
			case 1:$new_shuzi='00000'.$new_shuzi;break;
			case 2:$new_shuzi='0000'.$new_shuzi;break;
			case 3:$new_shuzi='000'.$new_shuzi;break;
			case 4:$new_shuzi='00'.$new_shuzi;break;
			case 5:$new_shuzi='0'.$new_shuzi;break;
		}
		return $new_en.$new_shuzi;
	}

方法2:

function getNewBindCode($oldCode){
		if(empty($oldCode)){return 'AA000000';}
		$enToShuzi=array('A'=>1,'B'=>2,'C'=>3,'D'=>4,'E'=>5,'F'=>6,'G'=>7,'H'=>8,'J'=>9,'K'=>10,'L'=>11,'M'=>12,'N'=>13,'P'=>14,'Q'=>15,'R'=>16,'S'=>17,'T'=>18,'U'=>19,'V'=>20,'W'=>21,'X'=>22,'Y'=>23);
		$old_en_1=$enToShuzi[substr($oldCode,0,1)];
		$old_en_2=$enToShuzi[substr($oldCode,1,1)];
		$old_shuzi=intval(substr($oldCode,2));
		if($old_en_2==23){//是Y
			if($old_shuzi==999999){
				$new_en_1=$old_en_1+1;
				$new_en_2=1;
				$new_shuzi=0;
			}
			else {
				$new_en_1=$old_en_1;
				$new_en_2=1;
				$new_shuzi=$old_shuzi+1;
			}
		}
		else {
			$new_en_1=$old_en_1;
			$new_en_2=$old_en_2+1;
			$new_shuzi=$old_shuzi;
		}
		switch(strlen($new_shuzi)){
			case 1:$new_shuzi='00000'.$new_shuzi;break;
			case 2:$new_shuzi='0000'.$new_shuzi;break;
			case 3:$new_shuzi='000'.$new_shuzi;break;
			case 4:$new_shuzi='00'.$new_shuzi;break;
			case 5:$new_shuzi='0'.$new_shuzi;break;
		}
		$new_en=array_search($new_en_1,$enToShuzi).array_search($new_en_2,$enToShuzi);
		return $new_en.$new_shuzi;
	}

使用方法:

第一次:echo getNewBindCode(”);

第二次以后,用上次得到的传入参数,echo getNewBindCode($preCode);

分类: php学习 标签: , , ,
css.php