php 整型数字对称加密,适用 ID 加密展示

warning: 这篇文章距离上次修改已过793天,其中的内容可能已经有所变动。

程序开发过程中总是有一些自增ID信息会展现给前端,这样就给一些人可乘之机,通过遍历ID等方式获取到数据信息。

为了解决这个问题,想了很多办法,今天自己写了一个对称加密算法分享给大家。ID加密后展示到前端,后端先解密再处理。

代码如下,欢迎指正。

<?php
/**
 * 整型数字对称加密,使用场景:对ID加密后展示
 * 只适用整型数字
 * 使用时请重新生成密钥
 */
class IntCode{
    // 密钥(0-9A-Za-z)打乱,可使用str_shuffle()函数重新生成
    private $key = 'PTvNKJdjOyB3niF891XCspl7rHMQIkELVqYbm20ZGUWhfze5txSRowg4uDA6ac';
    
    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

php
最后修改于:2022年05月05日 05:29

添加新评论