代码拉取完成,页面将自动刷新
同步操作将从 superzlc/otp 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
<?php
class HOTP {
private $secret = null;
private $counter = 0;
public function __construct($secret = null, $counter = 0) {
$this->secret = $secret;
$this->counter = $counter;
}
public function setSecret($secret, $format = null) {
$this->secret = self::_convertSecret($secret, $format);
}
public function gen($counter = null) {
if ($counter === null) {
if ($this->counter === null) {
$this->counter = 0;
}
$counter = $this->counter;
}
return self::_gen($this->secret, $counter);
}
public function verify($token, $counter = null) {
if ($counter === null) {
if ($this->counter === null) {
$this->counter = 0;
}
$counter = $this->counter;
if ($token === $this->gen(counter)) {
$this->counter += 1;
return true;
}
return false;
}
return $token === $this->gen($counter);
}
private static function _gen($secret, $counter) {
$data = pack('NN', $counter / 4294967296, $counter & 0xFFFFFFFF);
$hash = hash_hmac('sha1', $data, $secret, true);
$offset = ord($hash[19]) &0xf;
$num = (ord($hash[$offset]) & 0x7F) << 24 |
(ord($hash[$offset + 1]) & 0xFF) << 16 |
(ord($hash[$offset + 2]) & 0xFF) << 8 |
(ord($hash[$offset + 3]) & 0xFF);
$num = $num % 1000000;
return sprintf("%06d", $num);
}
private static function _convertSecret($secret, $format) {
if (!is_string($secret))
throw Exception('参数错误');
if ('hex' === $format)
return hex2bin($secret);
else if ('base64' === $format)
return base64_decode($secret);
else if ('string' === $format || null === $format)
return $secret;
else
throw Exception('参数错误');
}
}
class TOTP {
private $hotp;
private $window = 3;
private $interval = 30;
public function __construct($secret = null, $window = 3, $interval = 30) {
$this->hotp = new HOTP($secret, 0);
$this->window = $window;
$this->interval = $interval;
}
public function setSecret($secret, $format = null) {
$this->hotp->setSecret($secret, $format);
}
public function gen($timestamp = null) {
$timestamp = empty($timestamp) ? (time() * 1000) : $timestamp;
$counter = floor($timestamp / 1000 / $this->interval);
return $this->hotp->gen($counter);
}
public function gen2($timestamp = null) {
$timestamp = empty($timestamp) ? (time() * 1000) : $timestamp;
$timestamp_second = $timestamp / 1000;
$counter = floor($timestamp_second / $this->interval);
$token = $this->hotp->gen($counter);
$step = $timestamp_second % $this->interval;
$refresh_time = $counter * $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, $timestamp = null) {
$$timestamp = empty($timestamp) ? (time() * 1000) : $timestamp;
$counter = floor($timestamp / 1000 / $this->interval);
for ($i = 0, $w = 0; ; $i++) {
if ($token === $this->hotp->gen($counter - $i))
return true;
if (++$w >= $this->window)
break;
if ($i > 0) {
if ($token === $this->hotp->gen($counter + $i))
return true;
if (++$w >= $this->window)
break;
}
}
return false;
}
}
/**
function test() {
echo "\n<pre>\n";
$p1 = new HOTP("123456", 0);
echo $p1->gen() . "\n"; # 186818
echo $p1->gen(1234) . "\n"; # 263197
echo ($p1->verify('263197', 1234) ? "TRUE" : "FALSE") . "\n";
$p2 = new TOTP("123456", 3, 30);
echo $p2->gen(1614054214456) . "\n"; # 330925
echo ($p2->verify('330925', 1614054214456) ? "TRUE" : "FALSE") . "\n";
$p3 = new TOTP('helloworld', 3, 30);
$p3->setSecret('helloworld', 'string');
$p3->setSecret('68656c6c6f776f726c64', 'hex');
$p3->setSecret('aGVsbG93b3JsZA==', 'base64');
echo $p3->gen(1614054214456) . "\n"; # 759440
echo ($p3->verify('759440', 1614054214456) ? "TRUE" : "FALSE") . "\n";
echo "\n</pre>\n";
}
test();
**/
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。