首页 专题 文章 代码 归档

将自增ID可逆加密的PHP函数

转自知乎的一位大佬:

<?php

/** 
 * 整型数字对称加密,使用场景:对ID加密后展示
 * 只适用整型数字
 * 使用时请重新生成密钥
 */  

class IntCode
{
    // 密钥(0-9A-Za-z)打乱,可使用str_shuffle()函数重新生成
    private $key = 'PTvNKJdjOyB3niF891XCsp7IrHQMIkELVqYbm20ZUGWfhze5xtSRowgu4DA6ac';

    public function encode($int)
    {
        //判断是否为整型
        if (! is_int($int)) {
            return '不是整型';
        }
        //将传入数字转换成十六进制分割成数组
        $hexArr = str_split(dechex($int));
        //将密钥分割成数组
        $keyArr = str_split($this->key);
        //密钥长度,推荐62
        $keyLen = count($keyArr);
        //随机数字
        $rand = mt_rand(0, $keyLen - 1);
        //将随机值压入结果开头
        $str = $keyArr[$rand];
        //验证码
        $verfy = $keyArr[($keyLen - $rand + strlen($int)) % $keyLen];
        //循环十六进制每一位数字,替换成密钥里的值
        foreach ($hexArr as $v) {
            $offset = hexdec($v) + $rand;
            $str .= $keyArr[$offset % $keyLen];
        }
        //将验证码压入结果末尾并返回
        return $str . $verfy;
    }

    public function decode($str)
    {
        //验证$str是否合法
        if (! preg_match('/^[0-9a-zA-Z]{2,10}$/', $str)) {
            return '字符不合法';
        }
        //将传入字符串分割成数组
        $strArr = str_split($str);
        //密钥
        $key = $this->key;
        //将密钥分割成数组
        $keyArr = str_split($this->key);
        //密钥长度
        $keyLen = count($keyArr);
        //十六进制数值
        $hex = '';
        //获取随机数
        $rand = strpos($key, array_shift($strArr));
        //获取验证码
        $verfy = array_pop($strArr);
        //循环每一个字串并转换成十六进制
        foreach ($strArr as $k => $v) {
            if (strpos($key, $v) >= $rand) {
                $hex .= dechex(strpos($key, $v) - $rand);
            } else {
                $hex .= dechex($keyLen - $rand + strpos($key, $v));
            }
        }
        //十六进制转换成十进制
        $dec = hexdec($hex);
        //判断验证码是否正确
        if ($verfy !== $keyArr[($keyLen - $rand + strlen($dec)) % $keyLen]) {
            return '校验错误,给定字符串不合法'; 
        }
        return $dec;
    }
}

//以下为测试内容
$intCode = new IntCode();
// echo $intCode->encode(98445);
// echo $intCode->decode('h1xss');

for ($i=9865; $i<19800; $i++) {
    $str = $intCode->encode($i);
    $int = $intCode->decode($str);
    echo $i . ' | ' . $int . ' | ' . $str . '<br>';
}

?>

亲测可用!

转自:https://zhuanlan.zhihu.com/p/29342308

此文阅读完毕,您可以:分享
二维码图片 扫描关注我们哟