关于验证码实现的另一个思路

最近在做一个项目。在涉及到关于忘记密码找回功能时,从用户体验角度去考虑,在申请找回密码表单中只有两个元素——Email输入文本框和一个提交按钮。应该说会很方便。

但在接下来测试的时候,突然发现,虽然方便一些,同时也有关于恶意动作的阻止策略,但某些意外因素仍旧无法避免。

因此考虑加上一个验证码,避免一些纯粹攻击性恶意申请动作(此类动作其实也可以用一个方式进行阻止,不过,因为某些原因在此不方便实现)。

原本验证码打算用一些比较成熟的开源的代码来实现(比如:Discuz!中的验证码类——/include/seccode.class.php就是一个不错的例子),但其实发现类似这些显示出的效果仍旧会出现“人”难识别的情况。

对于机器识别验证码图片字符的机理说实话了解不多,以我的知识,我觉得可能是利用图片色彩加上字库方式去分辨的。既然是这两个因素,那么图片色彩上如果过于复杂显然对于“人”也同样难以识别,这个因素可以大略不去考虑,从字库来说,我觉得如果验证码字符利用非常规字库去显示或许效果会很好——但我不清楚机器将什么字库作为“非常规”,因此,我决定利用图片组合的方式进行构建。

简单说,就是将事先做好的字符图片拼凑起来,字符图片可以使用多套然后随机选取,字符图片上的“字符”利用自己“个性设计”——比如,将常规的字库图形利用图片编辑软件加以变形、缩放等等。考虑到,字符涉及较多,因此设计遵循两个原则:一是要将某些模棱两可的字符排除掉(比如:L、1、i、0、O等),二是根据CSS Sprite的原理,将同类型的字符放到一个图片中——我自己称之为“字符库图片”。

经过设计,得到若干组的 字符库图片,然后再设计多种类型的“背景图片”,作为验证码的背景,略微增加一些识别干扰。设计的原则最重要的就是——易于人类识别。

由于字符是特定个数的(经过我的筛选剩余24个)字母和数字,因此很容易放到一个小的数组里,利用array_rand()函数以及shuffle()函数,很容易生成一个漂亮的随机字符串。利用字符串单元字符的特定“位置(其实与数组的键值是对应的)”可以很方便的在“字符库图片”中找到它的位置。利用imagecopymerge()函数轻松的将它们拼凑在一起。

这样最终就形成了一个验证码的显示。

配合验证码的验证,可以利用私有的加密函数将字符串原形加密后保存在cookie内,对用户提交后进行快速验证。

由于涉及到的数组、图片的数量都不大,因此对于压力负载情况很好。

组合图片不是这个思路的难处,难点在于如何设计“人类”能看懂的字符图形:)另外,对于字符图片的相对位置控制也是一个比较费思量的课题,好在通过一些位置上的计算也可以进行不规则的变化。

思路很简单,写了一个简单的应用类,设计了大概6组“字符库图片”和4组“背景图片”,加上测试也花了整整一个下午的时间,效果自认为还不错。

代码就不上了,其实代码很简单,每个人的算法都可能不一样,主要的难点在于“字符库图片”的设计和排序问题。

谁订阅了我的博客,有兴趣看代码的可以直接朝我要,不贴在这里了^_^

PS:最近做项目用最多的是jQuery,这个框架太爽了。通过这个了解到框架做事的确很轻松,可惜,接触PHP有年头了,某些观念和意识基本已经根深蒂固了,所以到现在还无法使用任何PHP的框架。同时对于面向对象的开发,我个人真的是不入门,我倒觉得面向过程也并非是网上说的一无是处——比如性能、比如理解力等等还是略胜上风的。呵呵,题外话,个人不喜欢(或不上路)并非宣传大家也不要用,事实上,我最近看到开源站最多的比如:ThinkPHP、CakePHP应该都还不错,否则也不会有人去用了(哈哈,我其实对于这两个真的一点都不了解~~)

标签:GD, PHP, 思路, 算法

评论当前被关闭。

Deepseath Modified from Green Hope Theme · Proudly powered by WordPress · 津ICP备09005418号-1  津公网安备 12010302001005号