存档

2016年2月 的存档

唯一随机数碰撞检测

2016年2月16日 2 条评论

在一个项目中,需要设计一个唯一的验证码用于线下的取票凭证,类似美团电影票取票码。要求是不能太长,太长了不方便用户记忆,太短的话重复几率太大。

其实计算机的随机数不是真正的随机数,是取的时钟的微秒纳秒之类的(忘了在哪看的过),只要样本数量够大是有碰撞的可能的,即便是md5加密,也不是有人出来说得到了md5的碰撞值。

怎么生成暂先不管,项目中的办法是随机数:

[pcsh lang=”php” tab_size=”4″ message=”” hl_lines=”” provider=”manual”]

rand(100000000,999999999)

[/pcsh]

为了检测到底在多大的订单量的时候发生唯一码碰撞,我写了下边的几行代码(PHP),需要用到pthread扩展支持多线程,php编译的时候也必须加上如下参数

–enable-maintainer-zts

由于会生成大量的码用于检测是否重复,这里用了memcached缓存

[pcsh lang=”php” tab_size=”4″ message=”随机码碰撞检测” hl_lines=”” provider=”manual”]

	$mem = new Memcached('certs-234432');
	$mem->addServer("192.168.37.7", 11211);
	$mem->flush();

//这里其实可以做单例写文件
	function record($str) {
		$f = '/tmp/log.cert';
		$handle = fopen($f, 'a+');
		fwrite($handle, $str);
		fclose($handle);
	}

	function work() {
		$mem = new Memcached('certs-234432');
		$mem->addServer("192.168.37.7", 11211);

		$f = false;
		$total = 10000000;
		$str = '';

		$t = microtime(true);

		for($i=0; $i<$total; $i++) {
		        $c = rand(100000000, 999999999);
		        if(!$mem->get($c)) {
					$mem->add($c, '1');
		        }else{
					$str = '循环次数'.number_format($total).",第".$i."\t次发生碰撞,". '碰撞的随机数是'.$c .",\t用时".( microtime(true) - $t ).'秒' .PHP_EOL;
					$f = true;
					echo $str;
					record($str);
					break;
		        }
		}

		if(!$f){
			$str = '循环次数'.number_format($total).",没有发生碰撞,";
			$str .= '用时:'.( microtime(true) - $t ).'秒' . PHP_EOL;
			record($str);
			echo $str ;
		}
	}

	class cert_threads extends Thread {
		public function run() {
			work(); 
		}
	}

	$res = array();

	for($j=0; $j<4; $j++) {
		$res[$j] = new cert_threads();
		$res[$j]->start();
	}

[/pcsh]

1000万次循环(1000万随机码)跑出来的结果是

1000万

1000万循环(随机码)

100万的结果是

100万

100万

可以明显的看出,100万一下数据量基本不会发生碰撞,发生的几次碰撞基本在104万,400万,500万,800万,所以,如果月订单量是百万级别,最好在随机码中加上月份唯一识别码。

这个只是随机数部分,完整的验证码在随机数前还有运动类型码,每个运动类型月订单量百万级别,我觉得未来3-5年基本上达不到吧。

 

如果行业发展很快,真的到了这个量级了,那么再加上时间吧

比如2015年6月,4位数字用1506,运动类型3位,随机码11位,一共18位,好像有点长。

可以在日期和运动类型上下功夫,比如15年06上线开始001,表示上线的第一个月。运动类型好像也没有必须用3位数999个运动类型那么多,变成2位,然后就是16位。

 

 

分类: PHP 标签:

git-1.8.3编译报错

2016年2月15日 评论已被关闭

较新的gitlab版本在git clone的时候会检查git的版本,1.7.2的不行了,要升级到1.8.3

升级过程中报

make[1]: *** [perl.mak] 错误 2

可以安装如下包解决问题。

yum install perl-ExtUtils-MakeMaker package -y

分类: git 标签: