找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 496|回复: 0

[discuz二开] Discuz验证码功能解析

[复制链接]
发表于 2024-3-28 08:27:31 | 显示全部楼层 |阅读模式 来自 河南省安阳市
discuz验证码功能主要在\uc_server\lib\seccode.class.php或/source/class/class_seccode.php文件中实现,这两个文件的代码基本一致,区别是一个运行于ucenter server,一个运行于discuz。下面的分析是针对ucenter server上的验证码功能。

discuz支持的验证码类型有图形、flash、音频和位图。在服务器安装了ming库(动态生成flash动画)的情况下,discuz默认使用flash验证码。如果未安装ming,已安装GD库的情况下,discuz会使用图片验证码,否则使用位图验证码。音频验证码则需要在代码中手动配置。

位图验证码
discuz代码中已事先保存了各种字母和数字的位图编码:

$numbers = array
                        (
                        'B' => array('00','fc','66','66','66','7c','66','66','fc','00'),
                        'C' => array('00','38','64','c0','c0','c0','c4','64','3c','00'),
                        'E' => array('00','fe','62','62','68','78','6a','62','fe','00'),
                        'F' => array('00','f8','60','60','68','78','6a','62','fe','00'),
                        'G' => array('00','78','cc','cc','de','c0','c4','c4','7c','00'),
                        'H' => array('00','e7','66','66','66','7e','66','66','e7','00'),
                        'J' => array('00','f8','cc','cc','cc','0c','0c','0c','7f','00'),
                        'K' => array('00','f3','66','66','7c','78','6c','66','f7','00'),
                        'M' => array('00','f7','63','6b','6b','77','77','77','e3','00'),
                        'P' => array('00','f8','60','60','7c','66','66','66','fc','00'),
                        'Q' => array('00','78','cc','cc','cc','cc','cc','cc','78','00'),
                        'R' => array('00','f3','66','6c','7c','66','66','66','fc','00'),
                        'T' => array('00','78','30','30','30','30','b4','b4','fc','00'),
                        'V' => array('00','1c','1c','36','36','36','63','63','f7','00'),
                        'W' => array('00','36','36','36','77','7f','6b','63','f7','00'),
                        'X' => array('00','f7','66','3c','18','18','3c','66','ef','00'),
                        'Y' => array('00','7e','18','18','18','3c','24','66','ef','00'),
                        '2' => array('fc','c0','60','30','18','0c','cc','cc','78','00'),
                        '3' => array('78','8c','0c','0c','38','0c','0c','8c','78','00'),
                        '4' => array('00','3e','0c','fe','4c','6c','2c','3c','1c','1c'),
                        '6' => array('78','cc','cc','cc','ec','d8','c0','60','3c','00'),
                        '7' => array('30','30','38','18','18','18','1c','8c','fc','00'),
                        '8' => array('78','cc','cc','cc','78','cc','cc','cc','78','00'),
                        '9' => array('f0','18','0c','6c','dc','cc','cc','cc','78','00')
                        );

其中,每个字符对应的列表的每一个元素都可以转化为一个8位的二进制数字,其中1表示白点,0表示黑点。上述代码中每个字符都对应10个元素,故discuz用一个10x8的位图表示一个字符,例如B对应的列表,转化为二进制后得到:

00000000
11111100
01100110
01100110
01100110
01111100
01100110
01100110
11111100
00000000

把0看成黑点,1看成白点,你就会得到一个黑底白字的字母B。discuz随机生成的4个字符进行组合,转换成位图,插入一些噪点,再输出给前端,验证码功能就完成了。

音频验证码
音频验证码的实现比较简单,如下面的代码,discuz将事先录制好的对应到每个字符的mp3文件进行连续播放:

header('Content-type: audio/mpeg');
for($i = 0;$i <= 3; $i++) {
        readfile($this->datapath.'sound/'.strtolower($this->code[$i]).'.mp3');
}

flash验证码
flash验证码的实现和位图验证码的实现类似,都是利用已有的编码,对随机生成的字符进行对应组合,再输出给前端:

flash验证码编码片段:

case 'B':$str .= 'moveTo('.$x_1.', '.$y_0.');lineTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');lineTo('.$x_1.', '.$y_2.');lineTo('.$x_2.', '.$y_1_5.');lineTo('.$x_1.', '.$y_1.');lineTo('.$x_2.', '.$y_0_5.');lineTo('.$x_1.', '.$y_0.');moveTo('.$x_0.', '.$y_1.');lineTo('.$x_1.', '.$y_1.');';break;
case 'C':$str .= 'moveTo('.$x_2.', '.$y_0.');lineTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');lineTo('.$x_2.', '.$y_2.');';break;
case 'E':$str .= 'moveTo('.$x_2.', '.$y_0.');lineTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');lineTo('.$x_2.', '.$y_2.');moveTo('.$x_0.', '.$y_1.');lineTo('.$x_1.', '.$y_1.');';break;
case 'F':$str .= 'moveTo('.$x_2.', '.$y_0.');lineTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');moveTo('.$x_0.', '.$y_1.');lineTo('.$x_1.', '.$y_1.');';break;
case 'G':$str .= 'moveTo('.$x_2.', '.$y_0.');lineTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');lineTo('.$x_2.', '.$y_2.');lineTo('.$x_2.', '.$y_1.');lineTo('.$x_1.', '.$y_1.');';break;
case 'H':$str .= 'moveTo('.$x_0.', '.$y_0.');lineTo('.$x_0.', '.$y_2.');moveTo('.$x_2.', '.$y_0.');lineTo('.$x_2.', '.$y_2.');moveTo('.$x_0.', '.$y_1.');lineTo('.$x_2.', '.$y_1.');';break;


图形验证码
图形验证码支持gif动图、jpg和png。主要是利用GD库的功能进行图片合成,字体取自ttf文件,背景取自static/image/seccode/background/文件夹中的图片,由于实现过程有点繁杂,而本文重点关注其大致原理,所以这里就不深入解析了。

版权声明:本文遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tomatomas/article/details/107002161

发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;

如何回报帮助你解决问题的坛友,好办法就是点击帖子下方的评分按钮给对方加【金币】不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号

关闭

站长推荐上一条 /1 下一条

QQ|侵权投诉|广告报价|手机版|小黑屋|西部数码代理|飘仙建站论坛 ( 豫ICP备2022021143号-1 )

GMT+8, 2024-4-27 18:10 , Processed in 0.039138 second(s), 8 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表