无聊的时候统计了一下历年以来(1998至今)我在自己的电脑上曾经购买配置的硬件。很多东西记不清了,大致罗列如下:
台式机:
- 显示器:实达14寸、三星15寸、三星17寸、三菱22寸。
- CPU:奔腾MMX166、赛扬300A、毒龙700、奔四1.2G、奔四2.8G。
- 主板:精英???、磐英???、华硕P4PE、微星865GV、梅捷SY-15GV。
- 显卡:Intel740、TNT2、GForce2、华硕7300LE。
- 声卡:Yamaha724、红辣椒???、创新Audigy。
- 内存:64M×2、256M×2、512M×2。
- 硬盘:昆腾2.1G(大脚)、昆腾6.4G、昆腾20G、希捷60G、希捷160G、西数3200YS。
- 音箱:3.1一只、5.1一只。
- 光驱:美达52、NEC DVD ROM、SONY DVD ROM、先锋DVR-108。
- 打印机:佳能StyleColor440、三星ML-1430。
笔记本:
- DELL Latitude V-740
- 笔记本硬盘:IBM 80G。
- 笔记本内存:Kingstone 512M DDR。
真是不列不知道,一列吓一跳。太铺张浪费了!
最普通的思路就是加上验证信息。并考虑到以下因素:
一、验证信息不应当妨碍正常用户。因此,最好不要让用户去填验证码,而是由程序自动完成。它带来的问题是,智能化的spam程序有可能偷取验证信息。因而有以下设想:
二、验证信息应当是随时变化的。这是为了防止spam程序一劳永逸地偷取验证信息,提高其偷取验证信息的成本。
三、验证信息应当是可定制的。这是为了防止spam程序掌握了随时间变化的规律后自己计算生成验证信息。
四、验证信息应当是加密过的。这是为了防止spam程序掌握了定制的参数后自己计算生成验证信息。
考虑到以上因素,我设想了如下的验证方法:
假设原始的留言页面的url为comment.asp?id=1,加上验证信息后url变为comment.asp?id=1&code=xxxxxxxx。其中“xxxxxxxx”为验证码。验证码由以下方法产生:
xxxxxxxx=md5(A+B+C)。意即验证码按照3个参数求和后经MD5处理生成。其中三个参数为:A:时间因素,B:文章id,C:网站自定字符串。通过这种方法生成的验证码是spam程序无法伪造的。
还要说明的是,上面的时间因素A会产生一些问题。正常用户可能在一个页面停留一段时间以后才发表评论,但是此时时间因素A已经发生变化。对此可以采取的方法是,时间因素给予一天的宽限期,以适应用户在晚上12时打开页面却在第二天提交信息的情况。
如果主页面是静态的怎么适应随时变动的验证信息呢?把评论表单放在IFRAME中可以解决这一问题。
剩下的问题是,如何防止spam程序直接从网页源码中抓取验证码呢?从理论上来说这是不能避免的,页面的源码是程序产生的,因此一定可以用正则表达式从网页源码中抓取验证码。但是可以采取一些办法加大正则表达式匹配的难度,比如用url使用jscript生成就可以产生无数种变化。把相应的jscript代码放在外部的js文件中,就可以随意改变url生成的办法,又不影响页面的静态化。
这样处理后,虽然不能根本杜绝spam程序直接从网页源码中抓取验证码,但是大大增加了spam程序编写的难度。