otp短信php,otp.php

class HOTP {

private $secret = '123456';

private $window = 3;

private $counter = 0;

public function __construct($secret = "123456", $window = 3, $counter = 0) {

$this->secret = empty($secret) ? "123456" : $secret;

$this->window = $window < 0 || $window > 100 ? 50 : $window;

$this->counter = $counter;

}

public function gen($counter = null) {

if ($counter === null) {

if ($this->counter === null) {

$this->counter = 0;

}

$counter = $this->counter;

$ret = $this->gen($counter);

$this->counter += 1;

return $ret;

}

$dataStr = $this->longToString($counter);

$bytes = $this->hmacSHA1Encrypt($dataStr);

$num = $this->convert($bytes);

$num = $num % 1000000;

return sprintf("%06d", $num);

}

public function verify($token, $counter = null) {

if ($counter === null) {

if ($this->counter === null) {

$this->counter = 0;

}

$counter = $this->counter;

return $this->verify($token, $counter);

}

for ($i = 0; $i < $this->window; $i++) {

{

$tcounter = $counter - $i;

if ($token === $this->gen($tcounter))

return $i;

}

if ($i === 0)

continue;

{

$tcounter = $counter + $i;

if ($token === $this->gen($tcounter))

return $i;

}

}

return null;

}

private function hmacSHA1Encrypt($dataStr) {

$secretStr = $this->secret;

$hash = hash_hmac('sha1', $dataStr, $secretStr);

$bytes = Array();

foreach(str_split($hash, 2) as $hex) {

$hmac[] = hexdec($hex);

}

return $hmac;

}

private function convert($bytes20) {

$offset = $bytes20[19] & 0xf;

$v = ($bytes20[$offset] & 0x7F) << 24 |

($bytes20[$offset + 1] & 0xFF) << 16 |

($bytes20[$offset + 2] & 0xFF) << 8 |

($bytes20[$offset + 3] & 0xFF);

return $v;

}

private function bytesToString($bytes) {

$str = '';

foreach($bytes as $ch) {

$str .= chr($ch);

}

return $str;

}

private function longToBytes($v) {

$bytes = Array();

$vlow = $v & 0xFFFFFFFF;

$vhigh = floor($v / 4294967296); // 没有long类型,使用除以2^32代替右移32位

$bytes[] = (($vhigh >> 56) & 0xFF);

$bytes[] = (($vhigh >> 48) & 0xFF);

$bytes[] = (($vhigh >> 40) & 0xFF);

$bytes[] = (($vhigh >> 32) & 0xFF);

$bytes[] = (($vlow >> 24) & 0xFF);

$bytes[] = (($vlow >> 16) & 0xFF);

$bytes[] = (($vlow >> 8) & 0xFF);

$bytes[] = (($vlow >> 0) & 0xFF);

return $bytes;

}

private function longToString($v) {

$bytes = $this->longToBytes($v);

$ret = $this->bytesToString($bytes);

return $ret;

}

}

class TOTP {

private $hotp;

private $interval = 30;

public function __construct($secret = "123456", $window = 3, $interval = 30) {

$this->hotp = new HOTP($secret, $window, 0);

$this->interval = $interval;

}

public function gen($timestamp = null) {

$timestamp = empty($timestamp) ? (time() * 1000) : $timestamp;

$timestamp_second = $timestamp / 1000;

$tcounter = floor($timestamp_second / $this->interval);

return $this->hotp->gen($tcounter);

}

public function gen2($timestamp = null) {

$timestamp = empty($timestamp) ? (time() * 1000) : $timestamp;

$timestamp_second = $timestamp / 1000;

$tcounter = floor($timestamp_second / $this->interval);

$token = $this->hotp->gen($tcounter);

$step = $timestamp_second % $this->interval;

$refresh_time = $tcounter * $this->interval;

return array("token" => $token,

"loop_length" => $this->interval,

"loop_step" => $step,

"refresh_interval" => $this->interval * 1000,

"refresh_time" => $refresh_time * 1000,

"timestamp" => $timestamp

);

}

public function verify($token) {

$now = time();

$tcounter = floor($now / $this->interval);

return $this->hotp->verify($token, $tcounter);

}

}

/**

echo "

";

$totp1 = new TOTP("hello", 3, 30);

echo json_encode($totp1->gen2(), JSON_PRETTY_PRINT);

echo $totp1->verify('975046');

echo "

";

**/

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值