通过加密计算出短信验证码,无需缓存验证码
class XixiOtp { private $iKeeptime; // 验证码有效期 private $sKey; // 加密的密钥 private $p1Len = 1; // 验证码前缀长度(建议1~2) private $p2Len = 5; // 验证码后缀长度(建议3~7) public function __construct($sKey, $iKeeptime = 600) { $this->sKey = $sKey; $this->iKeeptime = $iKeeptime; } public function setAccount($sAccount) { // 设置要生成的账号 $this->sAccount = $sAccount; } public function numPad($n, $len) { return str_pad($n, $len, '0', STR_PAD_LEFT); } private function getP2($iT1, $iP1) { // 通过时间和验证码前缀来计算验证码的后缀 $iT2 = intval(($iT1 - $iP1 * $this->iKeeptime / pow(10, $this->p1Len)) / $this->iKeeptime); $sP1 = $this->numPad($iP1, $this->p1Len); $crc = crc32($this->sAccount . $iT2 . $sP1 . $this->sKey); $iP2 = $crc % pow(10, $this->p2Len); return $this->numPad($iP2, $this->p2Len); } public function getCode() { // 取得Otp验证码 $iT1 = time(); $m = $iT1 % $this->iKeeptime; $iP1 = intval($m * pow(10, $this->p1Len) / $this->iKeeptime); $iP2 = $this->getP2($iT1, $iP1); return $this->numPad($iP1, $this->p1Len) . $iP2; } public function verify($code) { // 校验Otp验证码是否有效 $iT1 = time(); $sP1 = substr($code, 0, $this->p1Len); $sP2 = substr($code, $this->p1Len); return $sP2 === $this->getP2($iT1, intval($sP1)); } public static function test() { // 测试代码 $iKeeptime = 30; $otp = new XixiOtp('xixikey', $iKeeptime); $otp->setAccount('[email protected]'); $sCode = $otp->getCode(); echo($sCode . "\r\n"); for ($i = 0; $i <= $iKeeptime; $i++) { echo $i . ':'; var_dump($otp->verify($sCode)); sleep(1); } } } XixiOtp::test();
可用于发邮件或短信验证码,无需创建表存储验证码
标签:iKeeptime,function,缓存,验证码,p1Len,PHP,public,iT1 From: https://www.cnblogs.com/xiangxisheng/p/16906720.html