我有一种情况,脚本从用户接收一些数据,然后返回一个哈希.在一段时间内,比如说X秒,哈希是有效的,并且当与原始数据一起提供回脚本时,并且在指定的时间范围内,允许访问某些功能.
我这样做是通过在哈希中包含一个时间戳.我可以通过调用say来获取时间戳,floor(time()/X);
但是这样,而不是在X秒后过期,在1到X秒之间到期.我通过保存time()%X
并将其附加到哈希来解决这个问题,然后当我收到它,解析它并从中减去它时time()
,所以我的哈希函数看起来有点像这样:
function hash($oldhash='') {
static $hash;
if(!$hash) {
$time = time();
$expoff = explode('!', $oldhash, 2);
$expoff = $expoff[0] ? $expoff[0] : $time%$this->_cfg['hashexpire'];
$hash = $expoff.'!'.sha1($this->_data.floor(($time-$expoff)/$this->_cfg['hashexpire']));
}
return $hash;
}
Run Code Online (Sandbox Code Playgroud)
还有盐在那里,但为了清楚起见我删除了它.
这是有效的,但我认为可能有更好的方法来实现我在这之后的想法,并想知道你是否有任何建议.
好吧,您希望它在一定秒数后过期,对吗?那么,为什么不预先计算过期时间并传递它呢?您只是在谈论正在传输的一些额外字节:
function makeHash() {
$expire = time() + $this->_cfg['hashexpire'];
$hash = $expire . ':' . hash_hmac('sha1', $this->_data, $expire);
return $hash;
}
Run Code Online (Sandbox Code Playgroud)
然后验证:
function verifyHash($hash) {
if(!strpos($hash, ':')) return false;
list ($expire, $rawhash) = explode(':', $hash, 2);
$testhash = hash_hmac('sha1', $this->_data, $expire);
if ($expire < time() && $testhash == $rawhash) {
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
请注意,它使用HMAC对数据有效负载进行“签名”。
如果您真的对数据大小很偏执,请在将base_convert($expire, 10, 36)
其发送给客户端之前,然后在验证时对其进行解码。
编辑: 当我重读你的问题时,我不确定。您是否正在寻找要生成的哈希值,该哈希值将在$x
几秒钟后失效?或者您是否希望在$x
几秒的绝对时间窗口内生成相同的哈希值(此后哈希值会发生变化)?如果是之前的情况,上述解决方案将起作用。如果是后者,那么你可以尝试这样的事情:
function makeHash() {
$time = time();
$startTime = $time - ($time % $this->_cfg['hashexpire']);
return hash_hmac('sha1', $this->_data, $startTime);
}
Run Code Online (Sandbox Code Playgroud)
其工作原理是,它与当前窗口的第一个有效秒的时间戳进行散列。这将始终保持不变,因此无需存储它或走得更远......
请注意,生成的哈希值每秒都会更改$_cfg['hashexpire']
。但它可能在创建后立即失效。因此,仅当您确实需要时才使用它。}
归档时间: |
|
查看次数: |
2025 次 |
最近记录: |