防垃圾信息灌水的智能验证码

WBOY
Libérer: 2016-06-23 14:15:30
original
969 Les gens l'ont consulté

最近系统经常遇到广告机发的垃圾信息攻击。很多人想到的方法是增强验证码的难度,或者做一些问答来防止。但是这样在防止广告机的同时,对正常用户的使用和体验也造成很大困难。这里提供一个智能验证码的思路。

即:在短时间内成功使用验证码后,验证码使用频率记录+1。短时间内下次生成时,将自动增加长度和难度。终极变态验证码就是扭曲的中文即可。

大致代码如下:
建立一个c_iphistory数据表,用来记录验证码使用频率。

CREATE TABLE IF NOT EXISTS `c_iphistory` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `ip` varchar(255) NOT NULL,  `num` int(11) NOT NULL,  `lastdateline` int(11) NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `ip` (`ip`)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='使用验证码的ip对应次数';
Copier après la connexion


生成验证码部分:
$freq = 60;//定义洪水攻击的频率	//检查是否已存储	$tmp = db::r("select * from c_iphistory where ip='$_G[ip]'");	$len = 2;	$type = 0;	if($tmp && $tmp['num'] > 0) {		$num = $tmp['num'];		$timeout = TS - $tmp['lastdateline'];		$num -= floor($timeout / $freq);//洪水指数降多少级		if($num < 0) $num = 0;		$len += $num;	}	if($len > 3){//倍增难度,长度2-5位		$type = floor($len / 4);		if($type > 8) {			$type = 8;			$len -= 34;		}else{			$len   = $len % 4;			$len += 2;		}	}else{		$len += 2;	}	$secode = s::rrand($len, $type);//下面就用$secode生成图片并记录到验证码库中以备验证即可。//************************函数部分****************************//	/**	 *	随机数 @zairwolf	 *	 */	function rrand($len, $type = 7) {//1 - Number //2 - Lower Char //4 - Upper Char //8 - Chinese		mt_srand((double)microtime() * 1000000);		switch($type) {			case 0:				$charlist = '012';				break;			case 1:				$charlist = '0123456789';				break;			case 2:				$charlist = 'abcdefghijklmnopqrstuvwxyz';				break;			case 3:				$charlist = '0123456789abcdefghijklmnopqrstuvwxyz';				break;			case 4:				$charlist = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';				break;			case 5:				$charlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';				break;			case 6:				$charlist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';				break;			case 7:				$charlist = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';				break;			case 8://使用中文				global $Ccharlist;				if(!$Ccharlist) $Ccharlist = file_get_contents("lib/disturbTxt.lib");				break;		}		$str = '';		if($type == 8) {			$max = strlen($Ccharlist) / 3-1;			for($i = 0; $i < $len; $i++) $str .= substr($Ccharlist, mt_rand(0, $max) * 3, 3);		}else {			$max = strlen($charlist) - 1;			for($i = 0; $i < $len; $i++) $str .= $charlist[mt_rand(0, $max)];		}		return $str;	}
Copier après la connexion


验证码验证部分
//在验证码检查确认正确之后,进行如下操作$freq = 60;//定义洪水攻击的频率	//检查是否已存储	$tmp = db::r("select * from c_iphistory where ip='$ip'");	if(!$tmp) {		$s = array(			'ip'	=> $ip,			'num'	=> 1,			'lastdateline'	=> TS,		);		db::i("insert into c_iphistory set ".sqlcol($s));	}else{//更新洪水攻击记录		$timeout = TS - $tmp['lastdateline'];		if($timeout > $freq){//超过1分之前发的,已有记录--			$num = $tmp['num'] - 1;			if($num < 0) $num = 0;			$s = array(				'num'	=> $num,				'lastdateline'	=> TS,			);			db::q("update c_iphistory set ".sqlcol($s)." where id='$tmp[id]'");		}else{			$num = $tmp['num'] + 1;			$s = array(				'num'	=> $num,				'lastdateline'	=> TS,			);			db::q("update c_iphistory set ".sqlcol($s)." where id='$tmp[id]'");		}	}
Copier après la connexion


思路供参考。TS为time()。其它几个地方,估计大家都能看懂。


回复讨论(解决方案)

本帖最后由 PhpNewnew 于 2013-02-06 14:31:09 编辑

暂时没验证代码 也没仔细看 不过思路和分享的精神要先表扬...

感谢分享。收藏了。

思路不错。 学习了。。

刚接触PHP,代码看不太懂。我的疑问是:这样使用数据库,对服务器会造成多大的压力?

想法不错,而且现在百度、新浪微博都是这么做的。

不过实际中可不能把这个值记录在mysql中,否则光这个查库和写库操作就够受的了。
可以在内存数据库中使用hash表来存储这个值,hash key可以用session_id。

感觉这样鸭梨有点大。  难道用数组存储?

想法不错,而且现在百度、新浪微博都是这么做的。

不过实际中可不能把这个值记录在mysql中,否则光这个查库和写库操作就够受的了。
可以在内存数据库中使用hash表来存储这个值,hash key可以用session_id。

n内存数据库是啥玩意儿?? 就是放在内存是不是?? 

好想法。~!

思路不错,收藏了,实现起来还不是那么容易说。思路不错,谢谢了。

这让我想起贴吧的那些验证码。

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal