PHP简单的手机验证码验证过程

做过一个需求:广告主后台发起调查活动,普通用户参加此调查后跳转值某个网址领取1Q点(1角钱);上线一段时间以后,广告主反馈得到的很多手机号都是伪造的(我们开始只用正则匹配判断手机号正确与否),然后产品让我们加上手机短信验证,就变成了下面的样子.

[img]http://dl2.iteye.com/upload/attachment/0100/6987/162fb4b8-3ff5-3f5d-b01a-54bf868a9798.png[/img]


刚开始的思路应该很正常的那种,用rand生成随机码,然后存在redis里边,设置expire为60秒;后来考虑考虑,用户为了1角钱不至于如此,需要验证码的时候也不会瞎填写,系统还限制某ID用户明天每天只能参加5次这种活动,也为了不浪费系统资源的原则,公司发的短信已经需要2分钱一条,决定不用redis,用下面的思路:

用用户帐号+活动ID+手机号进行处理生成一个固定的数字,然后驾驶时间戳进行干扰生成4位数的数字,干扰以后只保证4位数对应的二进制的1、5、6、7、8、9位不被干扰,这样对应会生出pow(2,6)个不一样的4位数字,随机发送给用户一个。

用户验证验证码时候也只验证验证码的1、5、6、7、8、9位是否正确,为用户帐号+活动ID+手机号进行处理生成,这样就不用存储验证码,达到验证手机号的号码。

具体的测试例子在下面,为啥说是测试例子呢,因为最后还没有用,我就去封闭开发其他项目去了,下面代码也是偶尔翻到,看代码竟然是我工作一周年的时候写的 :D :D ,测试的代码生成的验证码散列的不是很好,也没有时间进行改善,主要介绍一下上面的思路。


<?php
/**
*
* User: shikiliu
* Date: 13-7-11
*/
class TelephoneCheck
{


/**
* 取得某个用户某次活动的手机验证码
* @param $uin 用户ID 小于10000系统保留
* @param $actId 活动ID 小于1000系统保留
* @param $telephone 用户手机号
* @return bool|int 4位数的验证码
*/
public function getTelephoneCode($uin, $actId, $telephone)
{

if ($uin < 10000 || $actId < 1000 || empty($telephone)) {
return false;
}

$time = time();

$timeFeature = hexdec(substr(md5($time), 0, 3)) & 0x1F1;

$telephoneFeature = hexdec(substr(md5($telephone), 8, 4));

$actIdFeature = hexdec(substr(md5($actId), 16, 4));

$uinFeature = hexdec(substr(md5($uin), 24, 4));

$sumFeature = $telephoneFeature + $actIdFeature + $uinFeature;

$sumFeature = $sumFeature % 10000;

if ($sumFeature < 1000) {
$sumFeature = 5145;
}

$result = $sumFeature | $timeFeature;

return $result;
}


/**
* 验证用户的手机验证码
* @param $uin 用户ID 小于10000系统保留
* @param $actId 活动ID 小于1000系统保留
* @param $telephone 用户手机号
* @param $code getTelephoneCode生成的验证码
* @return bool 是否正确
*/
public function checkTelephoneCode($uin, $actId, $telephone, $code)
{

if ($uin < 10000 || $actId < 1000 || empty($telephone) || empty($code)) {
return false;
}

$telephoneFeature = hexdec(substr(md5($telephone), 8, 4));

$actIdFeature = hexdec(substr(md5($actId), 16, 4));

$uinFeature = hexdec(substr(md5($uin), 24, 4));

$sumFeature = $telephoneFeature + $actIdFeature + $uinFeature;

$sumFeature = $sumFeature % 10000;

if ($sumFeature < 1000) {
$sumFeature = 5145;
}

$sumFeature = $sumFeature & 0xE0E;

$code = $code & 0xE0E;

if ($sumFeature == $code) {
return true;
}
return false;
}
}


$actId = 10001;
$telephone = 13797025562;
$uin = 514540767;


$telCode = new TelephoneCheck();


$code = $telCode->getTelephoneCode($uin, $actId, $telephone);

var_dump($code);

var_dump($telCode->checkTelephoneCode($uin, $actId, $telephone, $code));

var_dump($telCode->checkTelephoneCode($uin, $actId, $telephone, $code+10));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值