PHP加密解密类:专用于数字ID与URL的混淆方案

顾星河
顾星河
发布时间:2026-10-14 | 6人浏览过
原创

在Web开发中,直接暴露数据库自增ID往往带来安全隐患,如泄露业务规模或引发遍历攻击。本文展示一个轻量级的PHP数字加密解密类,通过对数字进行字符替换和补位混淆,生成固定的非连续字符串,有效保护URL参数和内部标识。

核心设计目标

该方案主要解决以下问题:

  • 隐藏数据总量:通过非递增的密文,让外部无法推断数据库记录总数。
  • 防止遍历:即使获取相邻ID的密文,也无法轻易推算出其他ID。
  • URL友好性:输出为字母数字混合串,适合嵌入网址参数。

注意:此类算法属于“混淆”而非高强度的密码学加密(如AES)。其目的是增加逆向难度和减少明文曝光,不适合存储密码等极高敏感信息。

算法原理简述

算法基于自定义的字符映射表,主要步骤如下:

  1. 初始化:定义一个包含62个字符(a-z, A-Z, 0-9)的基础字符串。
  2. 分段提取:
    • 标记区:取前N位,用于编码原始数字的长度。
    • 替换区:取紧接着的10位,建立原数字0-9到密文字符的映射。
    • 补位区:剩余字符用于填充密文,使总长度固定并增加复杂度。
  3. 编码过程:根据输入数字长度确定标记位,计算补位字符,并通过映射表替换数字部分。
  4. 解码过程:读取首位确定数字长度,截取对应长度的尾部密文,通过反向映射还原数字。

完整代码实现

以下是完整的 XDeode 类实现。使用时需引入该类文件,实例化后即可调用 encode() 和 decode() 方法。

<?php
/**
 * 加密解密类
 * 该算法仅支持加密数字。比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密。
 * @author 深秋的竹子
 * @version alpha
 */
class XDeode{
 private $strbase = "Flpvf70CsakVjqgeWUPXQxSyJizmNH6B1u3b8cAEKwTd54nRtZOMDhoG2YLrI";
 private $key,$length,$codelen,$codenums,$codeext;

 function __construct($length = 9,$key = 2543.5415412812){
   $this->key = $key;
   $this->length = $length;
   $this->codelen = substr($this->strbase,0,$this->length);
   $this->codenums = substr($this->strbase,$this->length,10);
   $this->codeext = substr($this->strbase,$this->length + 10);
 }

 function encode($nums){
   $rtn = "";
   $numslen = strlen($nums);
 
 //密文第一位标记数字的长度
   $begin = substr($this->codelen,$numslen - 1,1);
 
 //密文的扩展位
   $extlen = $this->length - $numslen - 1;
   $temp = str_replace('.', '', $nums / $this->key);
   $temp = substr($temp,-$extlen);
 
   $arrextTemp = str_split($this->codeext);
   $arrext = str_split($temp);
   foreach ($arrext as $v) {
     $rtn .= $arrextTemp[$v];
   }
 
   $arrnumsTemp = str_split($this->codenums);
   $arrnums = str_split($nums);
   foreach ($arrnums as $v) {
     $rtn .= $arrnumsTemp[$v];
   }
   return $begin.$rtn;
 }

 function decode($code){
   $begin = substr($code,0,1);
   $rtn = '';
   $len = strpos($this->codelen,$begin);
   if($len!== false){
     $len++;
     $arrnums = str_split(substr($code,-$len));
     foreach ($arrnums as $v) {
       $rtn .= strpos($this->codenums,$v);
     }
   }
 
   return $rtn;
 }
}

// 使用示例
$begin = 9950;
$end = $begin + 50;
$obj = new XDeode(9);
for($i=$begin;$i<$end;$i++){
  $en = $obj->encode($i);
  $de = $obj->decode($en);
  echo "[{$i}]=[{$en}]=[{$de}]<br/>";
}
?>

运行结果验证

执行上述代码后,控制台/浏览器将输出加密前后的对比数据。可以看出,连续的整数被转换为了看似随机的短字符串,且解密能完美还原原始值。

[9950]=[vmizxPPga]=[9950]
[9951]=[vSNSSPPgk]=[9951]
[9952]=[vNQNyPPgV]=[9952]
[9953]=[vyyJJPPgj]=[9953]
[9954]=[vNzQzPPgq]=[9954]
[9955]=[vyNzmPPgg]=[9955]
[9956]=[vXxSNPPge]=[9956]
[9957]=[vXJJJPPgW]=[9957]
[9958]=[vXziQPPgU]=[9958]
[9959]=[viXxSPPgP]=[9959]
[9960]=[vQxmyPPea]=[9960]
[9961]=[viJyJPPek]=[9961]

集成建议

  1. 数据库字段:建议在表中保留原始ID作为主键或唯一索引,新增一列存储加密后的ID,或在应用层动态处理。
  2. 路由匹配:在接收到前端传参时,先调用 decode() 恢复原始ID,再进行数据库查询。
  3. 配置灵活性:__construct 中的 $key 可作为盐值修改,若希望不同项目拥有不同密文风格,可传入不同的Key值。

以上就是PHP针对数字ID进行加密和解密的详细内容,更多关于PHP数据安全与URL优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表