字符串自带有效期的验证

来源:互联网 发布:sql查询前五条数据 编辑:程序博客网 时间:2024/05/17 19:20

通过 md5 加密后的字符串本身不具有效期限,而且值是恒定的。想要每次获取的值不一样而且能通过验证,就需要时间戳或随机数的参与,详见代码和注释:


/** * Encode * @param string $key 固定值,不传输 * @param string $str 参与加密的字符串, 自定义 * @return string */function hashEncode($key, $str = ''){$time = strtotime(date('Y-m-d H:i', time()));// 位数只能到 16, 超过后字母可能超过  f$posStr = mt_rand(0, 1) . mt_rand(1, 6); // ASCII  65 - 90 A-Z, 参考 ASCII表$hashPos = intval($posStr); // 截取的起始位置$hash = md5($key . $str);$hashCode = substr($hash, $hashPos, 4);$signCode = md5($hash .$time. $hashCode);$ascType = $hashPos > 10 ? 54 : 47; // 使用 asc 的字母或数字的 asc 数值, 数字的起始值为 48, 字母为 65, 避开中间的特殊字符$sign = substr($signCode, 0, $hashPos). $hashCode .substr($signCode, $hashPos, -6). strtolower(chr( $hashPos + $ascType )) . substr($signCode, -1);return $sign;}/** * 验证 * @param string $sign 加密后的字符串 * @param string $key 固定值,不传输 * @param string $str 参与加密的字符串, 自定义 须与hashEncode中的一致 * @return boolean */function hashVerify($sign, $key, $str = ''){$time = strtotime(date('Y-m-d H:i', time()));$suffix = substr($sign, -2, 1);$ascCode = ord(strtoupper($suffix));$ascType = $ascCode > 64 ? 54 : 47;$hashPos = $ascCode - $ascType;$hash = md5($key . $str);$hashCode = substr($sign, $hashPos, 4);//$signCode = md5($hash . $time . $hashCode);//$code = substr($signCode, 0, $hashPos) . $hashCode . substr($signCode, $hashPos, -6) . $suffix . substr($signCode, -1);//避免时间增长, 有效期  60分钟$expires = 60;for($i = 0; $i < $expires; $i++){$signCode = md5($hash .$time. $hashCode);$code = substr($signCode, 0, $hashPos) . $hashCode . substr($signCode, $hashPos, -6) . $suffix . substr($signCode, -1);if($sign == $code){return true;}$time -= 60; //每次向前推60秒即1分钟}return false;}


示用:

//请求方$key = 'test';$sign = hashEncode($key);//接受方$key = 'test';$sign = isset($_GET['sign']) ? addslashes($_GET['sign']) : '';$verify = hashVerify($sign, $key);var_dump($verify);


原创粉丝点击