Discuz! X2验证码的产生和验证及随机数产生探讨

2019-02-17 21:05:00王振洲

submitcheck 函数一般只填写前两个参数即可,第一个参数表示要验证的表单元素的名字,此表单元素不存在则验证失败;第二个参数表示是否允许通过 GET 方式提交的数据通过验证,0 为不允许,1 为允许,一般为 0 即可。

后两个参数用于表示提交的表单中是否需要对验证码和验证问答做验证,第三个参数 $seccodecheck 代表验证码,第四个参数 $secqaacheck 代表验证问答,参数值都是 0 为不验证,1 为验证。

所以如果需要在提交后验证验证码,则至少要填写 3 个参数,即 submitcheck('passwordsubmit', 0, 1) 。

进入函数中会现对提交表单的提交方式、formhash、访问来源 referer 等数据进行安全性验证,通过后则会调用 check_seccode 函数对提交过来的验证码进行验证了,根据 check_seccode 的返回值,来给予不同的提示。 check_seccode 函数如何工作的参看 JS 验证中的 4) 即可。

至此通过 PHP 方式的验证码验证完成。

三、随机数如何产生的
Discuz! X的随机数是通过 random 函数产生的,函数在 source/function/function_core.php 文件


function random($length, $numeric = 0) {
$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
$hash = '';
$max = strlen($seed) - 1;
for($i = 0; $i < $length; $i++) {
$hash .= $seed{mt_rand(0, $max)};
}
return $hash;
}

此函数有两个参数,$length 表示要获取的随机数的位数,$numeric 表示是否要获取纯数字的随机数,取值 0 或 1。

函数首先使用 microtime 函数获取当前的微秒级时间戳字符串,然后在后面拼接上单前网站的根目录路径,然后进行 MD5 加密,获得 32 位长的字符串。之后对其进行转进制,如果要获取纯数字的随机数,则从 16 进制转为 10 进制,如果要获得数字和英文混杂的随机数,则从 16 进制转为 35 进制。之后再将转进制后获得的字符串,根据是否要获取纯数字随机数的区别,进行拼接。最后从拼接后的字符串中随机抽取随机数的第一位、第二位以此类推,直 至获取满足要求的随机数的位置为止。至此生成了随机数。